HDU-2102 A计划 (BFS)详解

目录

题目描述

输入

输出

样例

题解

样例解释

注意:

特殊样例

代码:


题目描述

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

输入

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

输出

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

样例

输入样例

1
5 5 14
S*#*.
.#...
.....
****.
...#.

..*.P
#.*..
***..
...*.
*.#..

输出样例

YES

题解
样例解释

'.'为平地可以通过的地方,'*'为墙不可通过

'#'为时空传输机可以传送到另一层的相同位置,例如(0,0,0)的传送器会传送到(1,0,0),而(1,0,0)的传送器会传送到(0,0,0)

'S'为起点,'P'为终点

值得注意的是此题层数只有两层

S为迷宫入口,每层迷宫长为N,宽为M,对于样例,N=5,M=5,T=14

从S(0,0,0)开始走到终点P(1,0,4)

第一层路径为

(0,0,0)——>(0,1,0)——>(0,2,0)——>(0,2,1)——>(0,2,2)——>(0,2,3)——>(0,2,4)——>(0,3,4)——>(0,4,4)——>(0,4,3)

走了9步

如下图

第二层路径为

(1,4,3)——>(1,4,4)——>(1,3,4)——>(1,2,4)——>(1,1,4)——>(1,0,4)

走了5步

箭头的个数为14即为移动所花的时间,坐传送器不需要时间,刚好等于T时间所以能拯救公主输出YES

迷宫问题中二维数组表示行和列,现在可以使用三维数组加一层,此题层数只有2层

注意:

如果传输器传送到的位置也是传送器,则这个传送器不可以使用(因为是否坐传送器是无法选择的,只要走到这个位置就必须坐这个传送器)

并且小于等于T时间都可以拯救公主

特殊样例

输入

2
2 2 100
S*
#*

**
#P
2 2 100
S*
#*

**
.P

输出

NO
YES
代码:
#include<cstring>
#include<iostream>
#include<queue>
using namespace std;
char dt[31][31][31];//存储地图
int st[31][31][31];//存储是否走过

/*上下左右四个方向*/
int dy[]={1,-1,0,0};
int dz[]={0,0,1,-1};

struct asd
{
	int x,y,z,step;
};
int n,m,k,sj;
int bj=0;
int js=0;
int q,w,e,qq,ww,ee;
void bfs()
{
	queue<asd>qwer;
	qwer.push({q,w,e,0});
	st[q][w][e]=1;
	while(!qwer.empty())
	{
		asd t=qwer.front();
		qwer.pop();
		if(t.x==qq&&t.y==ww&&t.z==ee)//找到终点则输出答案
		{
			bj=1;
			if(t.step<=sj)//在规定时间找到公主则输出YES
			{
				printf("YES\n");
			}
			else
			{
				printf("NO\n");
			}
			return ;
		}
		for(int i=0;i<4;i++){
			int y=dy[i]+t.y,z=dz[i]+t.z;
			int x=t.x;
			if(dt[x][y][z]!='*'&&dt[x][y][z]!='#'&&st[x][y][z]==0&&x>=1&&x<=n&&y>=1&&y<=m&&z>=1&&z<=k)//如果不是墙壁,并且没走过也没超出地图范围则走过去
			{
				
					st[x][y][z]=1;
					qwer.push({x,y,z,t.step+1});
			}
			else if(dt[x][y][z]=='#')//如果是传送器,则需要传送,总是会传送到另一层
			{
				if(x==1&&dt[x+1][y][z]!='*'&&dt[x+1][y][z]!='#'&&!st[x+1][y][z])//传送到第二层
				{
					st[x+1][y][z]=1;//标记传送到的位置为走过
					qwer.push({x+1,y,z,t.step+1});
				}
				if(x==2&&dt[x-1][y][z]!='*'&&dt[x-1][y][z]!='#'&&!st[x-1][y][z])//传送到第一层
				{
					st[x-1][y][z]=1;//标记传送到的位置为走过
					qwer.push({x-1,y,z,t.step+1});
				}
			}
		}
	}
}
int main()
{
	int t;
	scanf("%d",&t);
	while(t--)
	{
		bj=0;//初始化答案是否存在的标记
		scanf("%d %d %d",&m,&k,&sj);
		n=2;//此题只有两层
		for(int i=1;i<=n;i++){
			for(int j=1;j<=m;j++){
				for(int l=1;l<=k;l++){
					st[i][j][l]=0;//初始化走过的路的标记
			}
		}
		}
		bj=0;
		for(int i=1;i<=n;i++){
			for(int j=1;j<=m;j++){
				for(int l=1;l<=k;l++){
					cin>>dt[i][j][l];
					if(dt[i][j][l]=='S')//记录起点位置
					{
						q=i;
						w=j;
						e=l;
					}
					if(dt[i][j][l]=='P')//记录终点位置
					{
						qq=i;
						ww=j;
						ee=l;
					}
				}
			}
		}
		bfs();
		if(bj==0)//如果标记为0则表示没有一条路能找到公主,也输出no
		{
			printf("NO\n");
		}
	}
}
  • 13
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

星与星熙.

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值