A计划 HDU - 2102(题解)

A计划 HDU - 2102(题解)

可怜的公主在一次次被魔王掳走一次次被骑士们救回来之后,而今,不幸的她再一次面临生命的考验。魔王已经发出消息说将在T时刻吃掉公主,因为他听信谣言说吃公主的肉也能长生不老。年迈的国王正是心急如焚,告招天下勇士来拯救公主。不过公主早已习以为常,她深信智勇的骑士LJ肯定能将她救出。

现据密探所报,公主被关在一个两层的迷宫里,迷宫的入口是S(0,0,0),公主的位置用P表示,时空传输机用#表示,墙用表示,平地用.表示。骑士们一进入时空传输机就会被转到另一层的相对位置,但如果被转到的位置是墙的话,那骑士们就会被撞死。骑士们在一层中只能前后左右移动,每移动一格花1时刻。层间的移动只能通过时空传输机,且不需要任何时间。
Input输入的第一行C表示共有C个测试数据,每个测试数据的前一行有三个整数N,M,T。 N,M迷宫的大小N
M(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;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值