After eating too much fruit in Farmer John's kitchen, Bessie the cow is getting some very strange dreams! In her most recent dream, she is trapped in a maze in the shape of an N×M grid of tiles (1≤N,M≤1,000). She starts on the top-left tile and wants to get to the bottom-right tile. When she is standing on a tile, she can potentially move to the adjacent tiles in any of the four cardinal directions.
But wait! Each tile has a color, and each color has a different property! Bessie's head hurts just thinking about it:
- If a tile is red, then it is impassable.
- If a tile is pink, then it can be walked on normally.
- If a tile is orange, then it can be walked on normally, but will make Bessie smell like oranges.
- If a tile is blue, then it contains piranhas that will only let Bessie pass if she smells like oranges.
- If a tile is purple, then Bessie will slide to the next tile in that direction (unless she is unable to cross it). If this tile is also a purple tile, then Bessie will continue to slide until she lands on a non-purple tile or hits an impassable tile. Sliding through a tile counts as a move. Purple tiles will also remove Bessie's smell.
(If you're confused about purple tiles, the example will illustrate their use.)
Please help Bessie get from the top-left to the bottom-right in as few moves as possible.
INPUT FORMAT (file dream.in):
The first line has two integers N and M, representing the number of rows and columns of the maze.The next N lines have M integers each, representing the maze:
- The integer '0' is a red tile
- The integer '1' is a pink tile
- The integer '2' is an orange tile
- The integer '3' is a blue tile
- The integer '4' is a purple tile
The top-left and bottom-right integers will always be '1'.
OUTPUT FORMAT (file dream.out):
A single integer, representing the minimum number of moves Bessie must use to cross the maze, or -1 if it is impossible to do so.SAMPLE INPUT:
4 4
1 0 2 1
1 1 4 1
1 0 4 0
1 3 1 1
SAMPLE OUTPUT:
10
In this example, Bessie walks one square down and two squares to the right (and then slides one more square to the right). She walks one square up, one square left, and one square down (sliding two more squares down) and finishes by walking one more square right. This is a total of 10 moves (DRRRULDDDR).
Problem credits: Nathan Pinsker, inspired by the game "Undertale".
很有意思的迷宫题,BFS乱搞;
...
本来以为可以乱搞,但是挂了4个点;
挂了4个点的代码:
![](https://i-blog.csdnimg.cn/blog_migrate/8f900a89c6347c561fdf2122f13be562.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/961ddebeb323a10fe0623af514929fc1.gif)
1 #include<iostream>
2 #include<cstdio>
3 #include<cstring>
4 #include<algorithm>
5 #include<queue>
6 using namespace std;
7
8 inline void Read(int&);
9 const int maxn = 1000 + 5;
10 const int wx[4] = { 0, 0, 1, -1 };
11 const int wy[4] = { 1, -1, 0, 0 };
12 struct Stage
13 {//状态变量,存位置,走到该位置的步数以及Smell(f);
14 int x, y, k;
15 bool f;
16 };
17 int n, m, maze[maxn][maxn], dis[maxn][maxn][2];
18 queue<Stage>Q;
19 void BFS();
20
21
22 int main()
23 {
24 freopen("dream.in", "r", stdin);
25 freopen("dream.out", "w", stdout);
26 Read(n), Read(m);
27 for (int i = 1; i <= n; i++)
28 for (int j = 1; j <= m; j++)
29 Read(maze[i][j]);
30 BFS();
31 puts("-1");//搜完一遍没效果,输出-1;
32 return 0;
33 }
34
35 void BFS()
36 {
37 memset(dis, 0x7f, sizeof(dis));
38 Q.push((Stage) { 1, 1, 0, 0 });
39 while (!Q.empty())
40 {
41 Stage temp = Q.front();
42 Q.pop();
43 int x = temp.x, y = temp.y, k = temp.k;
44 bool f = temp.f;
45 if (dis[x][y][f] <= k) continue;
46 dis[x][y][f] = k;
47 if (x == n&&y == m)
48 {
49 printf("%d\n", k);
50 exit(0);//直接退出程序
51 }
52 for (int i = 0; i < 4; i++)
53 {
54 int tx = x + wx[i], ty = y + wy[i];
55 switch (maze[tx][ty])
56 {
57 case 0:
58 break;
59 case 1:
60 Q.push((Stage) { tx, ty, k + 1, f });
61 break;
62 case 2:
63 Q.push((Stage) { tx, ty, k + 1, 1 });
64 break;
65 case 3:
66 if (f) Q.push((Stage) { tx, ty, k + 1, 1 });
67 break;
68 case 4:
69 int tk = k + 1;
70 bool tf = 0;
71 while (maze[tx][ty] == 4)
72 {//模拟向前,实际上除非最后停留在'4'格,不然不会存储它的状态,即不会更新相关dis数组;
73 tf = 0;
74 if (maze[tx + wx[i]][ty + wy[i]] == 2)
75 tf = 1, tx += wx[i], ty += wy[i], tk++;
76 else if (maze[tx + wx[i]][ty + wy[i]] == 1 || maze[tx + wx[i]][ty + wy[i]] == 4)
77 tx += wx[i], ty += wy[i], tk++;
78 else break;
79 }
80 Q.push((Stage) { tx, ty, tk, tf });
81 break;
82 }
83 }
84 }
85 }
86
87 inline void Read(int &x)
88 {
89 x = 0;
90 bool f = 0;
91 char c = getchar();
92 while (c < '0' || c > '9')
93 {
94 f = (c == '-');
95 c = getchar();
96 }
97 while (c >= '0'&&c <= '9')
98 {
99 x = x * 10 + c - '0';
100 c = getchar();
101 }
102 if (f) x = -x;
103 }
那么问题在哪呢?
可以hack掉我程序的数据:...emmmmmmm没搞到合适的,但Dreif说是判重出了问题,对于'4',不同方向进入结果是不一样的,而我只维护了一个dis,听起来好像很有道理;
而我的程序只挂了4个点,只不过是因为我巧妙地避开了大部分停留在'4'的状态(其实...是我瞎猜的,我也不知道为什么过了这么多点lalala),撞到墙或不能过会使我不得不停下,这也就导致了问题出现,所以要开4维数组判重;
Dreif的AC代码(laji Dreif,这题他交了无数遍,口胡选手):
![](https://i-blog.csdnimg.cn/blog_migrate/8f900a89c6347c561fdf2122f13be562.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/961ddebeb323a10fe0623af514929fc1.gif)
1 //USACO 2015 December Contest, Gold
2 //Problem 3. Bessie's Dream
3 #include<iostream>
4 #include<cstdio>
5 #include<cstring>
6 #include<algorithm>
7 #include<queue>
8 using namespace std;
9
10 const int maxn = 1000 + 5;
11 const int wx[] = { 0, 1, -1, 0, 0 };
12 const int wy[] = { 0, 0, 0, 1, -1 };
13 struct State {
14 int x, y, k, d;
15 bool f;
16 };
17 int n, m, maze[maxn][maxn];
18 bool used[maxn][maxn][2][4];
19 queue<State>Q;
20
21 int main()
22 {
23 freopen("dream.in", "r", stdin);
24 freopen("dream.out", "w", stdout);
25 scanf("%d%d", &n, &m);
26 for (int i = 1; i <= n; i++)
27 for (int j = 1; j <= m; j++)
28 scanf("%d", &maze[i][j]);
29 Q.push((State) { 1, 1, 0, 0, 0 });
30 while (!Q.empty()) {
31 State temp = Q.front();
32 Q.pop();
33 int x = temp.x, y = temp.y, k = temp.k, d = temp.d;
34 bool f = temp.f, flag = 0;
35 if (used[x][y][f][d]) continue;
36 used[x][y][f][d] = 1;
37 if (x == n&&y == m) {
38 printf("%d\n", k);
39 return 0;
40 }
41 if (maze[x][y] == 4) {
42 int xx = x + wx[d], yy = y + wy[d];
43 if (!maze[xx][yy] || maze[xx][yy] == 3);
44 else if (maze[xx][yy] == 1 || maze[xx][yy] == 4)
45 Q.push((State) { xx, yy, k + 1, d, 0 }), flag = 1;
46 else Q.push((State) { xx, yy, k + 1, d, 1 }), flag = 1;
47 }
48 if (maze[x][y] == 4 && flag) continue;
49 for (int i = 1; i <= 4; i++) {
50 int xx = x + wx[i], yy = y + wy[i];
51 if (!maze[xx][yy] || (maze[xx][yy] == 3 && !f)) continue;
52 else if (maze[xx][yy] == 1 || (maze[xx][yy] == 3 && f) || maze[xx][yy] == 4)
53 Q.push((State) { xx, yy, k + 1, i, f });
54 else if (maze[xx][yy] == 2) Q.push((State) { xx, yy, k + 1, i, 1 });
55 }
56 }
57 puts("-1");
58 return 0;
59 }