寒假训练补题-第十一天-F6-三维BFS

这篇博客介绍了一个二维迷宫问题,公主被困在两层迷宫中,骑士需要通过三维BFS算法在限定时间内找到公主。输入包含迷宫尺寸和时间限制,输出是骑士能否按时找到公主的结果。给出的示例输入和输出显示,在给定条件下,骑士能够成功找到公主。
摘要由CSDN通过智能技术生成

可怜的公主在一次次被魔王掳走一次次被骑士们救回来之后,而今,不幸的她再一次面临生命的考验。魔王已经发出消息说将在T时刻吃掉公主,因为他听信谣言说吃公主的肉也能长生不老。年迈的国王正是心急如焚,告招天下勇士来拯救公主。不过公主早已习以为常,她深信智勇的骑士LJ肯定能将她救出。
现据密探所报,公主被关在一个两层的迷宫里,迷宫的入口是S(0,0,0),公主的位置用P表示,时空传输机用#表示,墙用*表示,平地用.表示。骑士们一进入时空传输机就会被转到另一层的相对位置,但如果被转到的位置是墙的话,那骑士们就会被撞死。骑士们在一层中只能前后左右移动,每移动一格花1时刻。层间的移动只能通过时空传输机,且不需要任何时间。

Input
输入的第一行C表示共有C个测试数据,每个测试数据的前一行有三个整数N,M,T。 N,M迷宫的大小NM(1 <= N,M <=10)。T如上所意。接下去的前NM表示迷宫的第一层的布置情况,后N*M表示迷宫第二层的布置情况。

Output
如果骑士们能够在T时刻能找到公主就输出“YES”,否则输出“NO”。

Sample Input
1
5 5 14
S*#*.
.#…

****.
…#.

.P
#.

**
.
*.#…

Sample Output
YES

ac代码:

#include<iostream>
#include<queue>
#include<cstring>
using namespace std;
int n, m, T, ex, ey, ez;//e表示终点
char a[10 + 1][10 + 1][2 + 1];
bool vis[10 + 1][10 + 1][2 + 1];
struct node
{
	int xx, yy, zz, time;
}person;
bool check(int x, int y, int z)
{
	if (x >= 1 && x <= n && y >= 1 && y <= m && (z == 1 || z == 2))//在界内
		if (a[x][y][z] != '*')//不为墙
			if (!vis[x][y][z])//未曾访问过
				return true;
	return false;
}
int rx[] = { 0,0,1,-1 };
int ry[] = { 1,-1,0,0 };
bool bfs()
{
	queue<node>Q;
	Q.push(person);
	node cur, next;
	while (!Q.empty())
	{
		cur = Q.front();
		Q.pop();
		vis[cur.xx][cur.yy][cur.zz] = true;
		if (cur.xx == ex && cur.yy == ey && cur.zz == ez && cur.time <= T)
			return true;
		if (cur.time > T)
			break;
		if (a[cur.xx][cur.yy][cur.zz] == '#')
		{
			next.xx = cur.xx;
			next.yy = cur.yy;
			if (cur.zz == 1)next.zz = 2;
			else next.zz = 1;
			if (check(next.xx, next.yy, next.zz))
				Q.push(next);
		}
		else
		{
			for (int i = 0; i < 4; i++)
			{
				next.xx = cur.xx + rx[i];
				next.yy = cur.yy + ry[i];
				next.zz = cur.zz;
				next.time = cur.time + 1;
				if (check(next.xx, next.yy, next.zz))
					Q.push(next);
			}
		}
	}
	return false;
}
int main()
{
	int K;
	cin >> K;
	while (K--)
	{
		cin >> n >> m >> T;
		memset(vis, false, sizeof(vis));
		for (int z = 1; z <= 2; z++)
		{
			for (int x = 1; x <= n; x++)
			{
				for (int y = 1; y <= m; y++)
				{
					cin >> a[x][y][z];
					if (a[x][y][z] == 'S')
					{
						person.xx = x;
						person.yy = y;
						person.zz = z;
						person.time = 0;
						vis[x][y][z] = true;
					}//标记起点
					else if (a[x][y][z] == 'P')
					{
						ex = x;
						ey = y;
						ez = z;
					}//标记终点
				}
			}
		}
		//接下来对时空传输机进行预处理
		for (int x = 1; x <= n; x++)
		{
			for (int y = 1; y <= m; y++)
			{
				if (a[x][y][1] == '#'&&a[x][y][2] == '#')
				{
					a[x][y][1] = '*';
					a[x][y][2] = '*';
				}
				else if (a[x][y][1] == '#'&&a[x][y][2] == '*')
				{
					a[x][y][1] = '*';
				}
				else if (a[x][y][2] == '#'&&a[x][y][1] == '*')
				{
					a[x][y][2] = '*';
				}
			}
		}
		if (bfs())
			cout << "YES" << endl;
		else
			cout << "NO" << endl;
	}
	return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值