Codeforces Round #416 (Div. 2) 811D Vladik and Favorite Game

Posted hyp1231

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Codeforces Round #416 (Div. 2) 811D Vladik and Favorite Game相关的知识,希望对你有一定的参考价值。

题目链接:

  http://codeforces.com/problemset/problem/811/D

题目描述:

D. Vladik and Favorite Game
 

  This is an interactive problem.

  Vladik has favorite game, in which he plays all his free time.

  Game field could be represented as n?×?m matrix which consists of cells of three types:

  • ?.? — normal cell, player can visit it.
  • ?F? — finish cell, player has to finish his way there to win. There is exactly one cell of this type.
  • ?*? — dangerous cell, if player comes to this cell, he loses.

  Initially player is located in the left top cell with coordinates (1,?1).

  Player has access to 4 buttons "U", "D", "L", "R", each of them move player up, down, left and right directions respectively. 

  But it’s not that easy! Sometimes friends play game and change functions of buttons. Function of buttons "L" and "R" could have been swapped, also functions of buttons "U" and "D" could have been swapped. Note that functions of buttons can be changed only at the beginning of the game.

  Help Vladik win the game!

Input

  First line contains two space-separated integers n and m (1?≤?n,?m?≤?100) — number of rows and columns respectively.

  Each of next n lines contains m characters describing corresponding row of field. Set of characters in field is described above.

  Guaranteed that cell with coordinates (1,?1) is normal and there is at least one way from initial cell to finish cell without dangerous cells.

Interaction

  You can press buttons no more than n·m times.

  To press a button you should print "U", "D", "L", "R" in new line. It’s necessary to print newline character and flush output. After flushing buffer you should read answer from input data. Answer is the pair of space-separated integers xy — new position of player. In case, if there is no cell in direction of moving, position will not change. If after any move player lost, in other words player move to dangerous cell, then x and y will be equal to ?-?1.

  If after any move player is in finish or dangerous cell, then you should terminate your program.

To finish output buffer (i. e. for operation flush) right after printing direction and newline you should do next:

  • fflush(stdout) in C++
  • System.out.flush() in Java
  • stdout.flush() in Python
  • flush(output) in Pascal
  • read documentation for other languages.
Example
input
4 3
...
**.
F*.
...
1 1
1 2
1 3
1 3
2 3
3 3
4 3
4 2
4 1
3 1
output
R
L
L
D
U
U
U
R
R
D

题目大意:

  给你n*m的迷宫,人物默认在(1,1),你有上下左右四个按钮,但上下或左右可能颠倒。

  需要根据你的操控以及程序返回的你的坐标判断按钮是否颠倒,并操纵人物到达终点。

思路:

  第一道交互式题目。

  因题目保证可以到达,先bfs出最短路径,用栈记录每次走得方向。

  然后假设按钮没有对调,正常输出。

  若发现位置和预期位置不同,则调整按钮指向,直到走到终点。

 

  (注:printf 后紧跟 fflush)

  (注+:dfs求路径T了……大概写得丑)

代码:

  

 1 #include <iostream>
 2 #include <cstdio>
 3 #include <cstring>
 4 #include <algorithm>
 5 #include <queue>
 6 #include <cstdlib>
 7 #include <stack>
 8 using namespace std;
 9 
10 const int N = 110;
11 
12 struct State {
13     int x, y, pre, p;
14     State(int x = 0, int y = 0, int pre = 0, int p = 0) :x(x), y(y), pre(pre), p(p) {}
15 }st[N*N * 2];  //结构体记录位置、上一个结构体的id(pre)、和上一步操作(p)
16 
17 int m, n, arr[N][N] = { 0 }, id = 0, ED, X, Y;
18 bool vis[N][N] = { 0 };
19 int a[4] = { 0,1,0,-1 };
20 int b[4] = { 1,0,-1,0 };
21 char out[4] = { R,D,L,U };  //初始假设没有对调按钮
22 stack<int> path;  //记录路径
23 
24 inline void read() {  //读图
25     char tmp[2];
26     scanf("%d%d", &m, &n);
27     for (int i = 1; i <= m; ++i)
28         for (int j = 1; j <= n; ++j) {
29             scanf("%1s", tmp);
30             if (tmp[0] == .)arr[i][j] = 1;
31             else if (tmp[0] == *)arr[i][j] = 0;
32             else arr[i][j] = 2;
33         }
34 }
35 
36 void bfs() {  //bfs求最短路
37     if (arr[1][1] == 2)exit(0);
38     vis[1][1] = true;
39     st[++id] = State(1, 1, 0, -1);
40     queue<int> que;
41     que.push(id);
42     while (!que.empty()) {
43         State& tmp = st[que.front()];
44         int now = que.front();
45         que.pop();
46         for (int i = 0; i < 4; ++i) {
47             int ta = tmp.x + a[i], tb = tmp.y + b[i];
48             if (ta <= 0 || tb <= 0 || ta > m || tb > n || vis[ta][tb] || !arr[ta][tb])continue;
49             vis[ta][tb] = true;
50             st[++id] = State(ta, tb, now, i);
51             if (arr[ta][tb] == 2) { ED = id; return; }
52             que.push(id);
53         }
54     }
55 }
56 
57 void make_path() {   //保存路径入栈
58     int pr = ED;
59     while (~st[pr].p) {
60         path.push(st[pr].p);
61         pr = st[pr].pre;
62     }
63 }
64 
65 inline void print(int t) {  //打印,并刷新缓冲区
66     printf("%c\n", out[t]);
67     fflush(stdout);
68     scanf("%d%d", &X, &Y);
69 }
70 
71 void play() {  //输出路径
72     int x = 1, y = 1;
73     while (!path.empty()) {
74         int tmp = path.top(); path.pop();
75         x += a[tmp], y += b[tmp];
76         print(tmp);
77         if (X != x || Y != y) {  //与预期不符
78             swap(out[tmp], out[(tmp + 2) % 4]);  //对调按钮
79             while (X != x || Y != y)print(tmp);  //返回预期位置
80         }
81     }
82 }
83 
84 int main() {
85     read();
86     bfs();
87     make_path();
88     play();
89 }

 

以上是关于Codeforces Round #416 (Div. 2) 811D Vladik and Favorite Game的主要内容,如果未能解决你的问题,请参考以下文章

Codeforces Round #416 (Div. 2) A+B

codeforces round #416 div2

Codeforces Round #416 (Div. 2) 811D Vladik and Favorite Game

Codeforces Round #416 (Div. 2)

(线段树+并查集) Codeforces Round #416 (Div. 2) E Vladik and Entertaining Flags

Codeforces Round #436 E. Fire(背包dp+输出路径)