HDU-2102-A计划

             Time Limit: 3000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)
                         Total Submission(s): 16672    Accepted Submission(s): 4189

Problem Description

可怜的公主在一次次被魔王掳走一次次被骑士们救回来之后,而今,不幸的她再一次面临生命的考验。魔王已经发出消息说将在T时刻吃掉公主,因为他听信谣言说吃公主的肉也能长生不老。年迈的国王正是心急如焚,告招天下勇士来拯救公主。不过公主早已习以为常,她深信智勇的骑士LJ肯定能将她救出。
现据密探所报,公主被关在一个两层的迷宫里,迷宫的入口是S(0,0,0),公主的位置用P表示,时空传输机用#表示,墙用*表示,平地用.表示。骑士们一进入时空传输机就会被转到另一层的相对位置,但如果被转到的位置是墙的话,那骑士们就会被撞死。骑士们在一层中只能前后左右移动,每移动一格花1时刻。层间的移动只能通过时空传输机,且不需要任何时间。

Input

输入的第一行C表示共有C个测试数据,每个测试数据的前一行有三个整数N,M,T。 N,M迷宫的大小N*M(1 <= N,M <=10)。T如上所意。接下去的前N*M表示迷宫的第一层的布置情况,后N*M表示迷宫第二层的布置情况。

Sample Input

这里写图片描述

Sample Output

YES

题目大意:简单的来说就是问你在给定T时间内能否到达从S点到达P点 不一定非要T时间 小于等于T时间则打印YES 反之则打印NO

题目思路:这道题dfs,bfs都可以过,不过要注意一些地方,下面我就以我过得DFS讲下思路,因为此题有两个图与之前做过的题的图多了一个,很多人都可能会认为写了两个dfs,其实完全没那个必要!可以把两个dfs压缩成一个,用一个参数来控制进入dfs是哪张图 首先我们要输入的时候记录下S P 的位置 这道题的S(起点貌似一直是0,0,0) 但P点貌似不是 要两张图片一起搜P记下P点的位置 并且记录下P点所在的哪个地图中。 在然而题目给了*为墙, #是传送门 ,当进入#跳到另一张图中对应位置 也是#,那么这个就会形成一个死循环 所有我们要把它优化下 不仅这种情况 还有当进入#跳到另一张图中对应位置的是墙,这也没必要了。
下面我就直接上代码了 。。。 HDU 31ms 过得

#include <iostream>
#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <algorithm>
#include <map>
#include <cmath>
#include <queue>
using namespace std;
int T,n,m,Z,cx,cy,zx,zy,st,ss;
bool flag;
char map1[15][15],map2[15][15];
int xx[4]={1,-1,0,0};
int yy[4]={0,0,1,-1};
void dfs(int x,int y,int cur,int s)//x,y分明为坐标  cur步数  s在第几张图中
{
      if(flag||cur<0)//若能到达或步数已经小于0
        return;
      if(x==zx&&y==zy&&s==ss)//当前x,y等于终点 并且s对应的图是终点所在的图
      {
          flag=true;//能够到达
          return;
      }
      else
      {
          for(int i=0;i<4;i++)
          {
              int xi=x+xx[i];
              int yi=y+yy[i];
              if(xi<0||yi<0||xi>=n||yi>=m)
                continue;
            if(s==1)//当在第一张图中
            {
            if(map1[xi][yi]!='*')//不为墙
            {
                if(map1[xi][yi]=='#')//若为传送门
                {
                    map1[xi][yi]='*';//标记墙 表示走过 节约时间
                    dfs(xi,yi,cur-1,2);//  步数-1   去第2张图中的当前位置
                    map1[xi][yi]='#';//退出 标记成为原来的传送门
                }
                else//为路
                {
                    map1[xi][yi]='*';//标记墙 表示走过
                    dfs(xi,yi,cur-1,1);// 步数-1  
                   map1[xi][yi]='.';//退出 标记成为原来的路
                }
            }
        }
        if(s==2)//当在第2张图中
        {
            if(map2[xi][yi]!='*')//不为墙
            {
                if(map2[xi][yi]=='#')//为传送门
                {
                    map2[xi][yi]='*';//标记墙 表示走过 节约时间
                    dfs(xi,yi,cur-1,1);//步数-1  传送到第一章图中的对应位置
                    map2[xi][yi]='#';//退出 标记成为原来的传送门
                }
                else//为路
                {
                    map2[xi][yi]='*';//标记墙 表示走过 节约时间
                    dfs(xi,yi,cur-1,2);//步数-1  
                    map2[xi][yi]='.';//退出 标记成为原来的路
                }
            }
        }
          }
      }
}
int main()
{
    scanf("%d",&T);//几组测试数据
    while(T--)
    {
        flag=false;
       scanf("%d%d%d",&n,&m,&Z);
       for(int i=0;i<n;i++)
       {
           scanf("%s",map1[i]);//输入第一个地图
       }
       for(int i=0;i<n;i++)
       {
           scanf("%s",map2[i]);//输入第二个地图
       }
       for(int i=0;i<n;i++)
       {
           for(int j=0;j<m;j++)
           {
               if(map1[i][j]=='S')//记录起点  并记下起点在哪个地图中
               {
                   cx=i;
                   cy=j;
                   st=1;
               }
               if(map1[i][j]=='P')//记录终点  并记下终点在哪个地图中
               {
                   zx=i;
                   zy=j;
                   ss=1;
               }
               if(map2[i][j]=='S')//记录起点  并记下起点在哪个地图中
               {
                   cx=i;
                   cy=j;
                   st=2;
               }
               if(map2[i][j]=='P')//记录终点  并记下终点在哪个地图中
               {
                   zx=i;
                   zy=j;
                   ss=2;
               }
               if(map1[i][j]=='#'&&map2[i][j]=='#')//当对应的位置两个地图都为# 直接标记为墙
               {
                   map1[i][j]='*';
                   map2[i][j]='*';
               }
               if(map1[i][j]=='#'&&map2[i][j]=='*')//当对应的位置分别为#和墙 直接标记为墙
               {
                   map1[i][j]='*';
                   map2[i][j]='*';
               }
               if(map1[i][j]=='*'&&map2[i][j]=='#')//当对应的位置分别为#和墙 直接标记为墙
               {
                   map1[i][j]='*';
                   map2[i][j]='*';
               }
            }
       }
       dfs(cx,cy,Z,st);//dfs过程   Z所给的步数   st  起点所在第几张图中
       if(flag)//能在给定时间内到达
        printf("YES\n");
       else//不能再给定时间内到达
        printf("NO\n");
    }
    return 0;
}

END!!!!!!!!!!!!!!!!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值