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 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 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 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 }
时间: 2024-11-05 14:54:22

Codeforces Round #416 (Div. 2) 811D Vladik and Favorite Game的相关文章

Codeforces Round #416 (Div. 2) C. Vladik and Memorable Trip

题目链接:Codeforces Round #416 (Div. 2) C. Vladik and Memorable Trip 题意: 给你n个数,现在让你选一些区间出来,对于每个区间中的每一种数,全部都要出现在这个区间. 每个区间的价值为该区间不同的数的异或值,现在问你这n个数最大的价值是多少. 题解: 比赛的时间直接就想到了做法,不过在选取合法区间的时候,细节上出了点小问题. 然后一直wa到怀疑人生.太菜了. 首先,先将合法的区间选取出来. 对于这些区间,按照左端点排序, 然后对于选出来的

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

In his spare time Vladik estimates beauty of the flags. Every flag could be represented as the matrix n?×?m which consists of positive integers. Let's define the beauty of the flag as number of components in its matrix. We call component a set of cel

【动态规划】 Codeforces Round #416 (Div. 2) C. Vladik and Memorable Trip

划分那个序列,没必要完全覆盖原序列.对于划分出来的每个序列,对于某个值v,要么全都在该序列,要么全都不在该序列. 一个序列的价值是所有不同的值的异或和.整个的价值是所有划分出来的序列的价值之和. 求整个的价值的最大值 f(i)表示最后一个划分序列的右端点为i时,1~i的答案. f(i)=max{max{f(j)}(1<=j<i)+xorsum(j+1,i)(j+1到i的区间合法)}(1<=i<=n) 需要在转移的时候,顺便处理f(i)的前缀max. 最终的答案就是所有f(i)的最大

【分类讨论】【spfa】【BFS】Codeforces Round #416 (Div. 2) D. Vladik and Favorite Game

那个人第一步肯定要么能向下走,要么能向右走.于是一定可以判断出上下是否对调,或者左右是否对调. 然后他往这个方向再走一走就能发现一定可以再往旁边走,此时就可以判断出另一个方向是否对调. 都判断出来以后,跑个spfa或者bfs就行了. 细节较多--有一些边界情况需要处理.比如终点在第一行或者第一列的情况. #include<cstdio> #include<queue> #include<cstring> #include<algorithm> using n

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

A. Vladik and Courtesy 2 seconds 256 megabytes At regular competition Vladik and Valera won a and b candies respectively. Vladik offered 1 his candy to Valera. After that Valera gave Vladik 2 his candies, so that no one thought that he was less gener

(dp) Codeforces Round #416 (Div. 2)

Vladik often travels by trains. He remembered some of his trips especially well and I would like to tell you about one of these trips: Vladik is at initial train station, and now n people (including Vladik) want to get on the train. They are already

Codeforces Round #416 (Div. 2)

B 前几天听cwy说O(m*n)被卡常,比赛时犹豫了好久才写,然后就A了,STL的常数很牛逼 大概2种方法:根据下标位置判断这个数值是否改变(找k-th min): 根据值来确定其下标,判断下标是否改变(找这个数是第几小,常数小) C n^2 dp,当时加了一些mark,实际上由于0?≤?ai?≤?5000,完全可以每次dp memset一波 D 交互题. 比赛时因为有一个for把3写成4,导致内存溢出,调了1个多小时都没有发现,还是太粗心(不过即使如此好像rank还是挺前面的..) 真可惜呀,

Codeforces Round #279 (Div. 2) ABCD

Codeforces Round #279 (Div. 2) 做得我都变绿了! Problems # Name     A Team Olympiad standard input/output 1 s, 256 MB  x2377 B Queue standard input/output 2 s, 256 MB  x1250 C Hacking Cypher standard input/output 1 s, 256 MB  x740 D Chocolate standard input/

Codeforces Round #428 (Div. 2)

Codeforces Round #428 (Div. 2) A    看懂题目意思就知道做了 #include<bits/stdc++.h> using namespace std; #pragma comment(linker, "/STACK:102400000,102400000") #define rep(i,a,b) for (int i=a; i<=b; ++i) #define per(i,b,a) for (int i=b; i>=a; --i