18.06.25 POJ4129 16年期末09:变换的迷宫
描述
你现在身处一个R*C 的迷宫中,你的位置用"S" 表示,迷宫的出口用"E" 表示。
迷宫中有一些石头,用"#" 表示,还有一些可以随意走动的区域,用"." 表示。
初始时间为0 时,你站在地图中标记为"S" 的位置上。你每移动一步(向上下左右方向移动)会花费一个单位时间。你必须一直保持移动,不能停留在原地不走。
当前时间是K 的倍数时,迷宫中的石头就会消失,此时你可以走到这些位置上。在其余的时间里,你不能走到石头所在的位置。
求你从初始位置走到迷宫出口最少需要花费多少个单位时间。
如果无法走到出口,则输出"Oop!"。
输入第一行是一个正整数 T,表示有 T 组数据。
每组数据的第一行包含三个用空格分开的正整数,分别为 R、C、K。
接下来的 R 行中,每行包含了 C 个字符,分别可能是 "S"、"E"、"#" 或 "."。
其中,0 < T <= 20,0 < R, C <= 100,2 <= K <= 10。输出对于每组数据,如果能够走到迷宫的出口,则输出一个正整数,表示最少需要花费的单位时间,否则输出 "Oop!"。样例输入
1
6 6 2
...S..
...#..
.#....
...#..
...#..
..#E#.
样例输出
7
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 #include <cstdio> 2 #include <string> 3 #include <memory.h> 4 #include <algorithm> 5 #include <stdlib.h> 6 #include <math.h> 7 #include <iostream> 8 #include<queue> 9 #include <set> 10 using namespace std; 11 12 int r, c, k; 13 int visited[105][105][15]; 14 int map[105][105]; 15 int sx, sy, ex, ey; 16 int dir1[4] = { 0,0,1,-1 }, dir2[4] = { 1,-1,0,0 }; 17 int flag = 0; 18 19 struct node{ 20 int time; 21 int x, y; 22 node(int _x, int _y) :x(_x), y(_y) { time = 0; } 23 }; 24 queue<node> all; 25 26 void bfs() { 27 while (!all.empty()) { 28 node now = all.front(); 29 all.pop(); 30 for (int i = 0; i < 4; i++) { 31 int xx = now.x + dir1[i], yy = now.y + dir2[i]; 32 node newone(now); 33 newone.x = xx, newone.y = yy; 34 newone.time = now.time + 1; 35 int tmptime = newone.time%k; 36 if (xx == ex && yy == ey) { 37 printf("%d\n", newone.time); 38 flag = 1; 39 return; 40 } 41 if (map[xx][yy]==1&&visited[xx][yy][tmptime] == 0||map[xx][yy]==2&& visited[xx][yy][tmptime] == 0&&tmptime==0) 42 { 43 all.push(newone); 44 visited[xx][yy][tmptime] = 1; 45 } 46 } 47 } 48 } 49 50 int main() 51 { 52 int t; 53 scanf("%d", &t); 54 while (t--) { 55 all = queue<node>(); 56 memset(visited, 0, sizeof(int) * 105 * 105 * 15); 57 memset(map, 0, sizeof(int) * 105 * 105 ); 58 flag = 0; 59 scanf("%d%d%d", &r, &c, &k); 60 for(int i=1;i<=r;i++) 61 for (int j = 1; j <= c; j++) { 62 char ch; 63 cin >> ch; 64 if (ch == '.') 65 map[i][j] = 1; 66 else if (ch == 'S') 67 { 68 map[i][j] = 1; 69 sx = i, sy = j; 70 } 71 else if (ch == 'E') { 72 map[i][j] = 1; 73 ex = i, ey = j; 74 } 75 else 76 map[i][j] = 2; 77 } 78 node origin(sx,sy); 79 all.push(origin); 80 visited[sx][sy][0] = 1; 81 bfs(); 82 if (!flag) 83 printf("Oop!\n"); 84 } 85 return 0; 86 }
思路:
很容易想到广搜,但是数据那么大,显然会TLE
那么怎么办呢?剪枝
很容易能知道,由于每过k单位时间,石头就会消失一次,那么当我们站在某点 (x,y) 时,时间为 t+k 和 t 时,它们之后行走面临的情境是完全一样的,那就意味着,对于某个状态的时间,我们可以取模后作为 visited[x][y][time] 的第三个变量,如果取模后的值代入发现已经访问过,那说明之前已经有更优越的情况出现过,不必再继续搜索了
注定失败的战争,也要拼尽全力去打赢它;
就算输,也要输得足够漂亮。