题目看链接:
https://vjudge.net/problem/HDU-2102
大致思路:
本来是一个很基础的走迷宫找最短路径的问题,因为加了一个比较特殊的传送门之后,让这道题的判断条件出了一点变化。正常的迷宫无非就三种状态,能走,是石头,走过了。然而这里加了第四种状态——传送门。就将判断条件变复杂了。
首先:
1.初步筛选,看它是不是在迷宫的范围之内以及有没有走过。
2.进行大致筛选:三个分支:
一是正常的路(空地,以及有公主的地方)
二不是正常的路,是传送门
三是墙走不通
3.进行最后的筛选
由于能不能走走传送门主要靠另一层的情况来决定:所以根据另一层的情况又有了分类:
一,因为另一层的该点有石头,或者是另一层的该点走过了,又或者是另一层的该点是一个传送门,走了之后会陷入死循环,所以不能走。
二,不属于以上的三种情况,说明还能走。
以下是代码:
#include <iostream>
#include<cstring>
#include<cstdio>
#include<queue>
#include<algorithm>
#include<cmath>
using namespace std;
#define MAX 11
char map[MAX][MAX][2];
//地图
bool vis[MAX][MAX][2];
//标记
int N,M,T;
//N,M,T
int px,py,pz;
//公主的位置
int flag,t;
//标记
struct node{
int x,y,z,step;
};
int dx[4]={1,-1,0,0};
int dy[4]={0,0,-1,1};
void bfs()
{
memset(vis,0,sizeof(vis));
int i;
vis[0][0][0]=1;//这里必须要标记为1
node u,v;
u.x=0;
u.y=0;
u.z=0;//起点
u.step=0;
queue<node> q;
q.push(u);
while(!q.empty())
{
u=q.front();
q.pop();
//找到了公主
if(u.x==px&&u.y==py&&u.z==pz)
{
flag=1;
t=u.step;
return;
}
//四个方向探寻
for(i=0;i<4;i++){
v.x=u.x+dx[i];
v.y=u.y+dy[i];
v.z=u.z;
//初步删选,两个条件,在边框内,还没走过
if(v.x>=0&&v.x<N&&v.y>=0&&v.y<M&&!vis[v.x][v.y][v.z])
{
//第一种情况能走,下一个点是公主的位置,或者下一个点是一个单纯的能走的位置即‘.’
if(map[v.x][v.y][v.z]=='.'||map[v.x][v.y][v.z]=='P')
{
v.step=u.step+1;
v.z=u.z;
vis[v.x][v.y][v.z]=1;
q.push(v);
}
//下一个是传送门
//这里又分为两种情况
//1.能经过传送门到达下一层
//2.到达下一层的该位置并不能走
else if(map[v.x][v.y][v.z]=='#')
{
int Z;
Z=(u.z+1)%2;
//已不能走的三个原因作为判断条件
//1.下一层中该位置:1.有墙2.走过了 3.有传送门(会陷入传送门的死循环)
if(map[v.x][v.y][Z]=='#'||map[v.x][v.y][Z]=='*'||vis[v.x][v.y][Z])
{
map[v.x][v.y][Z]='*';
map[v.x][v.y][v.z]='*';
//将这两个点封印为墙
//跳过这个点去下一层
continue;
}
else{
v.z=Z;
v.step=u.step+1;//这里step一定要加一
//因为走到上一层的这个位置要一个时间
q.push(v);
vis[v.x][v.y][v.z]=1;
}
}
//当为墙时自动跳过
}
}
}
return;
}
int main()
{
int S;
cin>>S;//测试组数
int i,j,k;
while(S)
{
S--;
//初始化墙
memset(map,0,sizeof(map));
cin>>N>>M>>T;
for(i=0;i<2;i++)
for(j=0;j<N;j++)
for(k=0;k<M;k++)
{
cin>>map[j][k][i];
if(map[j][k][i]=='P')
px=j,py=k,pz=i;
}//输入墙并找到公主
flag=0;
bfs();
//能就下公主的条件
if(flag==1&&t<=T)
cout<<"YES"<<endl;
else//否则不能救下公主
cout<<"NO"<<endl;
}
return 0;
}
//理解题意当到达了传送门的坐标的时候
//必定传送
//骑士们一进入时空传输机就会被转到另一层的相对位置
//不能跳过传送门到达该层的另一个空地
//回避传送门的条件
//1.传送到的另一层的相对位置是一个墙
//2.传送到的相对位置也是一个传送门无限传送
//3.传送到的相对位置已经走过了
//到了传送门如果满足条件立即前往另一层