题意: 王子想要从一个二层地牢中救出公主,问是否能在T s 之内救出公主,地牢起止位置为(0,0,0),*表示墙,王子没有本事踏足于上,一层地牢与二层地牢之间只能通过楼梯 # 到达另一层的相对位置,王子只能上下左右的移动。
思路: 裸BFS,遇到 # 就广度搜索到另一层,看最小时间是否小于等于 T 。
我所遇到的问题:
1.没有考虑到王子直接救不了公主。
2.两层地牢#与#重合,是使用不了的。
上代码:
#include<bits/stdc++.h>
using namespace std;
const int N=12;
int n,m,t;
char a[2][N][N];
int vis[2][N][N];
int dir[4][2]={{1,0},{-1,0},{0,1},{0,-1}};
struct node{
int x,y,z;
int time;
}e,s;
queue<node> que;
int check(int z,int x,int y)
{
if(x<1||x>n||y<1||y>m||vis[z][x][y]||a[z][x][y]=='*')
return 0;
return 1;
}
int bfs()
{
vis[0][1][1]=1;
s.x=1,s.y=1,s.z=0,s.time=0;
while(!que.empty()) que.pop();
que.push(s);
while(!que.empty())
{
node front=que.front();
que.pop();
if(front.time>t)
{
return 0;
}
if(front.x==e.x&&front.y==e.y&&front.z==e.z)
{
return 1;
}
for(int i=0;i<4;i++)
{
node tmp;
tmp.x=front.x+dir[i][0];
tmp.y=front.y+dir[i][1];
tmp.z=front.z;
if(check(tmp.z,tmp.x,tmp.y))
{
if(a[tmp.z][tmp.x][tmp.y]=='#')
{
vis[tmp.z][tmp.x][tmp.y]=1;
if(tmp.z==0)
tmp.z=1;
else
tmp.z=0;
if(check(tmp.z,tmp.x,tmp.y)&&a[tmp.z][tmp.x][tmp.y]!='#')
{
tmp.time=front.time+1;
que.push(tmp);
vis[tmp.z][tmp.x][tmp.y]=1;
}
}
else
{
tmp.time=front.time+1;
vis[tmp.z][tmp.x][tmp.y]=1;
que.push(tmp);
}
}
}
}
return 0;//如果救不了
}
int main()
{
int T;
cin>>T;
while(T--)
{
memset(vis,0,sizeof(vis));
cin>>n>>m>>t;
for(int k=0;k<2;k++)
{
for(int i=1;i<=n;i++)
{
for(int j=1;j<=m;j++)
{
cin>>a[k][i][j];
if(a[k][i][j]=='P')
e.z=k,e.x=i,e.y=j;
}
}
}
if(bfs())
puts("YES");
else
puts("NO");
}
return 0;
}