Minecraft 是著名的独立游戏,在全世界都有着极高的人气,玩家可以自己搭建服务器供全世界的玩家游玩,因此有些玩家搭建了一些专用的小游戏服务器,提供各种各样的小游戏,这也为 Minecraft 提供了更多的玩法。下面是其中一个小游戏:矿工冒险记。
现在你控制的人物在一个N×M的场地中,左上角的方格为 (0, 0),右下角为 (N – 1, M – 1),你一开始的位置在 (SX, SY),你家的位置则在 (EX, EY)。身为一个矿工,你身上早就有了好几组铁和钻石,所以你正匆忙地赶回家里。但是有某些格子被设下了陷阱,如果走到上面就会粉身碎骨,立刻 Game Over。你当然不想 Game Over,所以你要避开这些格子。
假设每单位时间能向上、下、左、右移动一个格子,请你计算一下最短回家的时间。
一个整数 T,表示有多少组测试数据。
接下来的 T 组测试数据,每组测试数据第一行是两个正整数 N, M (1 <= N, M <= 10),表示场地大小。
第二行有一个正整数 P (0 <= P <= N × M),表示有多少个方格被设下了陷阱。
接下来的 P 行,每行是两个整数 X, Y,表示陷阱坐标。
最后一行是四个整数 SX, SY, EX, EY,表示起始位置和家的位置。
注意,行走不能超出地图边界。
对于每组输入数据,输出一行一个数字,表示最少需要的回家时间。假如有不可能完成任务的情况,输出 -1。
1
3 3
2
1 1
1 2
0 0 2 2
4
#include <stdio.h> #include <queue> using namespace std; struct N { int x, y; int t; }; queue<N> Q; int go[4][2] = { -1, 0, 1, 0, 0, -1, 0, 1 }; bool mark[10][10]; int maze[10][10]; int n, m; int BFS(int x, int y){ while (!Q.empty()){ N now = Q.front(); Q.pop(); for (int i = 0; i < 4; i++){ int nx = now.x + go[i][0]; int ny = now.y + go[i][1]; if (nx < 0 || nx >= n || ny < 0 || ny >= m) continue; if (maze[nx][ny] == 1) continue; if (mark[nx][ny] == true) continue; mark[nx][ny] = true; N tmp; tmp.x = nx; tmp.y = ny; tmp.t = now.t + 1; Q.push(tmp); if (nx == x && ny == y) return tmp.t; } } return -1; } int main(){ int T, p, sx, sy, ex, ey; scanf("%d", &T); while (T--){ scanf("%d%d%d", &n, &m, &p); int xx, yy; for (int i = 0; i < n; i++){ for (int j = 0; j < m; j++){ maze[i][j] = 0; } } while (p--){ scanf("%d%d", &xx, &yy); maze[xx][yy] = 1; } for (int i = 0; i < n; i++){ for (int j = 0; j < m; j++){ mark[i][j] = false; } } scanf("%d%d%d%d", &sx, &sy, &ex, &ey); while (!Q.empty()) Q.pop(); N start; start.x = sx; start.y = sy; start.t = 0; Q.push(start); mark[sx][sy] = true; int rec = BFS(ex, ey); printf("%d\n", rec); } return 0; }