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;
}