现据密探所报,公主被关在一个两层的迷宫里,迷宫的入口是S(0,0,0),公主的位置用P表示,时空传输机用#表示,墙用*表示,平地用.表示。骑士们一进入时空传输机就会被转到另一层的相对位置,但如果被转到的位置是墙的话,那骑士们就会被撞死。骑士们在一层中只能前后左右移动,每移动一格花1时刻。层间的移动只能通过时空传输机,且不需要任何时间。
1 5 5 14 S*#*. .#... ..... ****. ...#. ..*.P #.*.. ***.. ...*. *.#..
YES
题解:一道用bfs求最短路径的问题,一开始做忽略两个细节,
1、进入‘#’后,不但遇到‘*’是走不了的,遇到‘#’同样走不了
2、进入‘#’后,有可能直接就碰到P,即next.f == pf && next.x == px && next.y == py
要特别注意,bfs中返回值0或者1 的时刻
AC代码:
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include <queue>
using namespace std;
struct node
{
int f,x,y,step;
};
char map[2][15][15];
int vis[2][15][15];
int mov[4][2] = {{1,0},{0,1},{-1,0},{0,-1}};
int c,n,m,t;
int pf , px , py ;
int check(int a,int b,int c) //检查是否越界
{
if( b<0 || c<0 || b>=m || c>=n)
return 1;
else if(map[a][b][c] == '*')
return 1;
return 0;
}
int bfs()
{
node a,next;
queue<node> Q;
a.f = 0 ; a.x = 0 ; a.y = 0 ; a.step = 0 ;
vis[0][0][0] = 1 ;
Q.push(a);
while(!Q.empty())
{
a = Q.front();
Q.pop();
if( a.f==pf && a.x==px && a.y==py ){
return 1 ;
}
if(a.step >= t) break ;
for(int i=0 ; i<4 ; i++)
{
next = a ;
next.x = a.x + mov[i][0];
next.y = a.y + mov[i][1];
next.step = a.step + 1 ;
if(check(next.f,next.x,next.y)) continue ;//非法,进入下一循环
if(vis[next.f][next.x][next.y]) continue;
vis[next.f][next.x][next.y] = 1 ;
if(map[next.f][next.x][next.y]=='#')
{
next.f = !next.f ;
if(check(next.f,next.x,next.y)) continue;
if(vis[next.f][next.x][next.y]) continue;
if(map[next.f][next.x][next.y]=='*'||map[next.f][next.x][next.y]=='#')
continue ;
vis[next.f][next.x][next.y] = 1 ;
}
if(next.f == pf && next.x == px && next.y == py)
{
return 1;
}
Q.push(next);
}
}
return 0;
}
int main(void)
{
cin >> c;
while(c--)
{
cin >> m >> n >> t ;
for(int i=0 ; i<2 ; i++)
{
for(int j=0 ; j<m ; j++)
for(int k=0 ; k<n ; k++)
cin >> map[i][j][k];
getchar();
}
for(int i=0 ; i<2 ; i++)
for(int j=0 ; j<m ; j++)
for(int k=0 ; k<n ; k++)
if(map[i][j][k]=='P') {
pf = i ; px = j ; py = k ;
}
memset(vis,0,sizeof(vis));
int ans = bfs();
if(ans) cout << "YES" << endl;
else cout << "NO" << endl;
}
return 0;
}