如题所示,一个两层的迷宫,骑士从S(0,0,0)进入迷宫,要在t时间内到达公主的所在地P,每次只能上下左右移动,'*'表示墙,'#'表示时空传输机,可以瞬间完成迷宫层次切换,即当骑士处于第1层的(x,y)位置时,可以传输到第2层的(x,y)位置
此题的解法很容易想到,bfs就可以,但是处理的情况稍微多了一点,有一种比较坑的情况,题目是有讲的,就是传输机的另一边是堵墙,骑士们会撞死
还有一种比较坑的地方是传输机的另一边还是传输机,这种情况就是陷入无穷无尽的传输中,本来以为把传输机的位置都标记为已访问过就万事大吉了,可惜还是太单纯了一点,WA了一次,后来就拿出来另外考虑了。
附代码如下:
#include<iostream>
#include<queue>
#include<cstdio>
#include<cstring>
using namespace std;
const int N = 15;
struct maze
{
int x,y,z,t;
maze(){}
maze(int x1,int y1,int z1,int t1):x(x1),y(y1),z(z1),t(t1){}
};
char a[2][N][N];
bool v[2][N][N];
int n,m,maxt,g[4][2]={{0,1},{1,0},{0,-1},{-1,0}};
bool BFS(int x,int y,int z,int t)
{
queue<maze> q;
memset(v,false,sizeof(v));
v[z][x][y]=true;
q.push(maze(x,y,z,t));
while(!q.empty())
{
maze u = q.front();
q.pop();
for(int i = 0;i < 4; i++)
{
x = u.x + g[i][0];
y = u.y + g[i][1];
z = u.z;
t = u.t + 1;
if(x >= 0 && x < n && y >= 0 && y < m && z >= 0 && z <= 1 && !v[z][x][y])
{
if(a[z][x][y] == '#')
{
v[z][x][y] = true;
if(a[z^1][x][y] != '*')
{
if(a[z^1][x][y] == 'P')
{
if(t <= maxt)
return true;
else
return false;
}
if(a[z^1][x][y] != '#')
q.push(maze(x,y,z^1,t));
v[z^1][x][y] = true;
}
}
else if(a[z][x][y] == 'P')
{
if(t <= maxt)
return true;
else
return false;
}
else if(a[z][x][y] != '*')
{
v[z][x][y] = true;
q.push(maze(x,y,z,t));
}
}
}
}
return false;
}
int main()
{
int c;
scanf("%d",&c);
while(c--)
{
scanf("%d %d %d",&n,&m,&maxt);
for(int i = 0;i < n; i++)
scanf("%s",a[0][i]);
for(int i = 0;i < n; i++)
scanf("%s",a[1][i]);
if(BFS(0,0,0,0))
puts("YES");
else
puts("NO");
}
return 0;
}