目录
题目描述
可怜的公主在一次次被魔王掳走一次次被骑士们救回来之后,而今,不幸的她再一次面临生命的考验。魔王已经发出消息说将在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"); } } }