简单的BFS:矿工冒险记

Minecraft 是著名的独立游戏,在全世界都有着极高的人气,玩家可以自己搭建服务器供全世界的玩家游玩,因此有些玩家搭建了一些专用的小游戏服务器,提供各种各样的小游戏,这也为 Minecraft 提供了更多的玩法。下面是其中一个小游戏:矿工冒险记。

现在你控制的人物在一个N×M的场地中,左上角的方格为 (0, 0),右下角为 (N – 1, M – 1),你一开始的位置在 (SX, SY),你家的位置则在 (EX, EY)。身为一个矿工,你身上早就有了好几组铁和钻石,所以你正匆忙地赶回家里。但是有某些格子被设下了陷阱,如果走到上面就会粉身碎骨,立刻 Game Over。你当然不想 Game Over,所以你要避开这些格子。

假设每单位时间能向上、下、左、右移动一个格子,请你计算一下最短回家的时间。

输入格式

一个整数 T,表示有多少组测试数据。

接下来的 T 组测试数据,每组测试数据第一行是两个正整数 NM (1 <= N, M <= 10),表示场地大小。

第二行有一个正整数 P (0 <= P <= N × M),表示有多少个方格被设下了陷阱。

接下来的 P 行,每行是两个整数 XY,表示陷阱坐标。

最后一行是四个整数 SXSYEXEY,表示起始位置和家的位置。

注意,行走不能超出地图边界。

输出格式

对于每组输入数据,输出一行一个数字,表示最少需要的回家时间。假如有不可能完成任务的情况,输出 -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;
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值