题目链接:
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 2·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 x, y — 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 11 21 31 32 33 34 34 24 13 1
output
RLLDUUURRD
题目大意:
给你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 }