描述
你现在身处一个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
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] 的第三个变量,如果取模后的值代入发现已经访问过,那说明之前已经有更优越的情况出现过,不必再继续搜索了
来源:oschina
链接:https://my.oschina.net/u/4274876/blog/3926875