A计划 HDU - 2102(题解)
可怜的公主在一次次被魔王掳走一次次被骑士们救回来之后,而今,不幸的她再一次面临生命的考验。魔王已经发出消息说将在T时刻吃掉公主,因为他听信谣言说吃公主的肉也能长生不老。年迈的国王正是心急如焚,告招天下勇士来拯救公主。不过公主早已习以为常,她深信智勇的骑士LJ肯定能将她救出。
现据密探所报,公主被关在一个两层的迷宫里,迷宫的入口是S(0,0,0),公主的位置用P表示,时空传输机用#表示,墙用表示,平地用.表示。骑士们一进入时空传输机就会被转到另一层的相对位置,但如果被转到的位置是墙的话,那骑士们就会被撞死。骑士们在一层中只能前后左右移动,每移动一格花1时刻。层间的移动只能通过时空传输机,且不需要任何时间。
Input输入的第一行C表示共有C个测试数据,每个测试数据的前一行有三个整数N,M,T。 N,M迷宫的大小NM(1 <= N,M <=10)。T如上所意。接下去的前NM表示迷宫的第一层的布置情况,后NM表示迷宫第二层的布置情况。Output如果骑士们能够在T时刻能找到公主就输出“YES”,否则输出“NO”。Sample Input1
5 5 14
S*#*.
.#…
…
****.
…#.
….P
#.…
**…
….
*.#…
Sample Output
YES
题解:
题目解决的关键就在与:
1.退出时的判断条件(找到公主位置,也就是等于P的时候退出)
2.时间的限制,题目中要求骑士要在一定时间内将公主解救出来(if(map.step>=time) break;时间多于规定时间,就不再进行搜索,退出本次循环
3.最重要的一点就是克服层次的转化,坑点就是#下一层必须是 。
不能对#和*,遇到墙撞死。
遇到‘#’一定要传过去
传过去只后记得要记录时间,即,传过去之前的时间(指的是到达#号的时间,传送不用记时间)
#include <iostream>
#include <cstring>
#include <algorithm>
#include <cstdio>
#include <queue>
using namespace std;
const int maxn = 15;
/* run this program using the console pauser or add your own getch, system("pause") or input loop */
int M,N,T,ex,ey,ez;
char map[2][maxn][maxn];
int vis[2][maxn][maxn];
int zou[4][2]={{1,0},{0,1},{-1,0},{0,-1}};
struct node{
//z记得是层
int x,y,z,step;
};
int check(int x,int y){//检查是否越界
if(x<0||x>=N||y<0||y>=M)
return 1;
else
return 0;
}
queue<node>q;
node now,nex;
void bfs(){
now.x=0;
now.y=0;
now.z=0;
now.step=0;
memset(vis,0,sizeof(vis));
vis[now.z][now.x][now.y]=1;//标记走过
q.push(now);
while(!q.empty()){
now=q.front();
q.pop();
if(now.step>T){//超出时间
break;
}
if(map[now.z][now.x][now.y]=='P'&&now.step<=T){//如果到达终点步数小于t
printf("YES\n");
return ;
}
for(int i=0;i<4;i++){
nex.x=now.x+zou[i][0];
nex.y=now.y+zou[i][1];
nex.z=now.z;
//如果越界。下一个是墙,或已经走过,跳过,不能入队
if(check(nex.x,nex.y)||map[nex.z][nex.x][nex.y]=='*'||
vis[nex.z][nex.x][nex.y])
continue;
//如果能传送,# 那么下一层必须是点 .
if(map[!nex.z][nex.x][nex.y]!='#'&&
//!nex.z等价于如果nex.z=1,则!nex.z=0||nex.z=0则nex.z=1
map[!nex.z][nex.x][nex.y]!='*'&&
map[nex.z][nex.x][nex.y]=='#'){
nex.step=now.step+1;
nex.z=1-nex.z;//层的转换
vis[nex.z][nex.x][nex.y]=1;
q.push(nex);
}else if(map[nex.z][nex.x][nex.y]=='.'||map[nex.z][nex.x][nex.y]=='P'){
nex.step=now.step+1;//传输过去记得也要记录时间
vis[nex.z][nex.x][nex.y]=1;
q.push(nex);
}
}
}
printf("NO\n");
}
int main(int argc, char** argv) {
int c;
scanf("%d",&c);
while(c--){
scanf("%d%d%d",&N,&M,&T);
for(int i=0;i<N;i++){
scanf("%s",&map[0][i]);
}
for(int i=0;i<N;i++){
scanf("%s",&map[1][i]);
}
while(!q.empty())//清空队列
q.pop();
bfs();
//printf("%d %d %d\n",ex,ey,ez);
}
return 0;
}