一开始我用的两个二维数组相互传递信息,WA死我了,考虑再多也考虑不全面
但是我还是考虑到了两个重要的点:
1.传送门传送过去的位置不可以也是一个传送门,这样会无限循环
2.传送门传送过去遇到一面墙,那这样走不通的,如果不撞南墙不回头,那是挂了的,但毕竟是搜索,可以搜出一条合
二维数组的代码远没有三维简洁
下面是正确的三维数组代码
#include <iostream>
#include <cstring>
#include <algorithm>
using namespace std;
const int N=40;
char map[2][N][N]; //定义一个三维数组
bool stt[2][N][N];
int dx[4]={-1,0,1,0};
int dy[4]={0,1,0,-1};
int c;
struct node
{
int k,x,y;
int dis;
}q[1600];
bool bfs(int n,int m,int st)
{
int hh=0,tt=-1;
q[++tt]={0,0,0,0}; //分别表示k,x,y,dis
stt[0][0][0]=true;
while(hh<=tt)
{
auto t=q[hh++];
if(map[t.k][t.x][t.y]=='P'&&t.dis<=st)
{
return true;
}
for(int i=0;i<4;i++)
{
int xx=t.x+dx[i];
int yy=t.y+dy[i];
if(t.dis+1>st)
continue;
if(xx>=0&&xx<n&&yy>=0&&yy<m&&map[t.k][xx][yy]!='*'&&!stt[t.k][xx][yy])
{
stt[t.k][xx][yy]=true;
//访问下一个点可以不带条件,但是放入队列要考虑额外条件
//因为有些情况是无效的
//cout<<"tu is "<<t.k<<" xx is "<<xx<<" yy is "<<yy<<endl;
//if(map[t.k][xx][yy]=='p'&&)
if(map[t.k][xx][yy]=='#')
{
int tkk=(t.k+1)%2;
if(map[tkk][xx][yy]!='#'&&map[tkk][xx][yy]!='*')
q[++tt]={tkk,xx,yy,t.dis+1}; //传送门的传递位置加入队列
stt[tkk][xx][yy]=true;
continue; //遇到传送门本身不用加入队列 ,其实就是把传递的位置代替传送门本来的位置
}
q[++tt]={t.k,xx,yy,t.dis+1}; //如果是其他情况则入队
//q[++tt]={t.k,xx,yy,t.dis+1};
}
}
}
return false;
}
int main()
{
cin>>c;
while(c--)
{
int n,m,t;
cin>>n>>m>>t;
memset(stt,false,sizeof stt);
for(int i=0;i<2;i++)
for(int j=0;j<n;j++)
for(int k=0;k<m;k++)
{
cin>>map[i][j][k];
}
if(bfs(n,m,t)==true)
cout<<"YES"<<endl;
else cout<<"NO"<<endl;
}
return 0;
}