解题
比较坑的就是讨论从本格子向另一层走还是本层左右上下移动。并不是所有从队列出来的格子都能进行上下左右移动的,只有非‘#’格子才能。
注意这一点后,就是一个常规的BFS了。
AC代码
#include <cstdio>
#include <iostream>
#include <cstring>
#include <algorithm>
#include <queue>
using namespace std;
const int maxn=12;
char g[2][maxn][maxn];
struct node
{
int z;//在第0层还是第1层
int x,y;//坐标
int t;//时间
node(int z,int x,int y,int t):z(z),x(x),y(y),t(t){}
};
int n,m,limit;
int si,sj,sk,ei,ej,ek;
bool vis[2][maxn][maxn];
bool valid(int x,int y,int z)
{
return x>=0 && x<n && y>=0 && y<m && g[z][x][y]!='*';
}
int dir[4][2]={0,1,0,-1,1,0,-1,0};
void bfs()
{
memset(vis,false,sizeof(vis));
queue<node> Q;
vis[sk][si][sj]=true;
Q.push(node(sk,si,sj,0));
while(!Q.empty())
{
node now=Q.front();Q.pop();
int z=now.z,x=now.x,y=now.y,t=now.t;
if(x==ei && y==ej && z==ek && t<=limit)
{
printf("YES\n");
return ;
}
if(g[z][x][y]=='#' && g[z^1][x][y]!='*' && g[z^1][x][y]!='#' && !vis[z^1][x][y])
{
vis[z^1][x][y]=true;
Q.push(node(z^1,x,y,t));
}
if(g[z][x][y]!='#')//注意别忘了,WA了几次在这里
for(int i=0; i<4; i++)
{
int fx=x+dir[i][0],fy=y+dir[i][1];
if(!valid(fx,fy,z) || vis[z][fx][fy])
continue;
vis[z][fx][fy]=true;
Q.push(node(z,fx,fy,t+1));
}
}
printf("NO\n");
}
int main()
{
int T;
scanf("%d",&T);
while(T--)
{
scanf("%d%d%d",&n,&m,&limit);
for(int i=0;i<n;i++)
scanf("%s",g[0][i]);
for(int i=0;i<n;i++)
scanf("%s",g[1][i]);
for(int k=0;k<2;k++)
for(int i=0;i<n;i++)
for(int j=0;j<m;j++)
{
if(g[k][i][j]=='S')
si=i,sj=j,sk=k;
if(g[k][i][j]=='P')
ei=i,ej=j,ek=k;
}
bfs();
}
return 0;
}