码迷,mamicode.com
首页 > 其他好文 > 详细

HDU 2102 A计划

时间:2015-08-09 17:19:52      阅读:191      评论:0      收藏:0      [点我收藏+]

标签:

A计划

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


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表示迷宫第二层的布置情况。
 

Output
如果骑士们能够在T时刻能找到公主就输出“YES”,否则输出“NO”。
 

Sample Input
1 5 5 14 S*#*. .#... ..... ****. ...#. ..*.P #.*.. ***.. ...*. *.#..
 

Sample Output
YES
 

Source
 
 
题意:
 
        输入三个数,分别代表你要找的地图的长和宽,注意是长宽相同的两层地图,然后第三个数代表的是限制的时间,看看你能不能够在这个已知的时间内找到终点,如果能输出YES;否则输出NO;一(0,0,0)为起点,P代表终点,*代表墙;点(.)代表路,#代表时空传输机(在这期间不花费时间)!
 
思路:
 
       这道题实在bfs的模板的基础上添加了一个判断语句就OK了,在做的时候遇到了很多麻烦,当一一攻克了,旅顺思路之后,感觉也没有多难了!在一个平面上做的和一层地图的做法相同,就是设四个坐标,然后以一个点为中心,在这个点周围找终点,找不到,就只能讲这个不是终点的点进行标记,然后放进队列,重新从队列里面找步数最少的(也是时间最少的)点,循环这个操作!这道题只不过需要在那个点出队列之后,进行判断是不是#,如果是,就只能进行上下移动了,而不能左右移动,当你上下移动过之后,然后再新点的基础上才能进行前后左右的移动,就这一点需要重点注意!在你上下移动的过程中,不是你想的那么一帆风顺的!会遇到哦很多的麻烦,当在第0层的时候,你需要向第一层移动,当在第一层的时候,你需要向第0层移动;当你移动到的那个点是#或者*的时候你就是死路一条了(因为两个#会让你在一直上下移动;一个*会让你撞在墙上);所以说遇到这两种情况就只能continue;然后重新再从队列里面找步数最短的开始执行;当你移动到的那个点是终点的时候,你很幸运,你就结束循环输出就行了;当你运行到的是一个点,你也不要高兴的太早,因为你有可能已经走过这条路不需要再走,再走也不是最短的路了;当你走到的是一个点,并且这个点是没走过的点,那么你真的太幸运了,通过了时空传输机,开始以新的点为起点,进一步的搜索吧!
 
 
代码:
 
 
//这道题整整花了我一天的时间!就是找不到错误,最终找到了三处错误的地方,在下面都标记过了
/*
这道题的思路和其他的广搜题大体一样,唯一的不同就是在上下的方向上有限制,所以你要在遇到#的 时候
要另外讨论是上,还是下,还是死路一条,所以,在解这道题的时候,就只分前后左右就行了,在上下的
时候应该在前后左右移动之前就得判断是否能上下,能上下移动的条件是所在的位置是#,并且#上面(或下面)
的位置是点(.),并且之前没有走过这个位置!然后当你移动过之后,你应该将矛头转向移动过之后的点
在它周围找终点;需要注意的是:当#上面(或者下面)是#或者是*号的时候,就只能思路一条了!也有可能就是终点
,你就到终点了! 
*/ 
#include <stdio.h>
#include <string.h>
#include <math.h>
#include <queue>
#include <algorithm>
#define INF 0xfffffff
using namespace std;
int n,m,t;
char map[2][11][11];//
int dx[4]={0,1,-1,0};
int dy[4]={1,0,0,-1};
int ex,ey,ez;
int ans,flag;
int vis[2][11][11];//
struct node 
{
    int x,y,z,step;
    friend bool operator < (node a,node b)
    {
        return a.step>b.step;
    }
}a,temp;
int judge()
{
    if(temp.x<0||temp.x>=n)    return 0;
    if(temp.y<0||temp.y>=m)    return 0;
    if(map[temp.z][temp.x][temp.y]=='*') return 0;//
    if(vis[temp.z][temp.x][temp.y]==1)    return 0;//
    if(temp.step>=ans)    return 0;//可以写成》=ans了,但是有规定的时间了!当时间大于规定时间的话,这条路就也不符合规定的路了 
    return 1;
}

void bfs()
{
    a.x=0;
    a.y=0;
    a.z=0;
    a.step=0;
    priority_queue<node>q;
    q.push(a);
    memset(vis,0,sizeof(vis));
    vis[0][0][0]=1;//
    while(!q.empty())
    {
        a=q.top();
        q.pop();
        if(map[a.z][a.x][a.y]=='#')
        {
            temp.x=a.x;
            temp.y=a.y;
            if(a.z==0)
            {
                temp.z=a.z+1;
            }
            else if(a.z==1)
            {
                temp.z=a.z-1;
            }
            if(map[temp.z][temp.x][temp.y]=='#'||map[temp.z][temp.x][temp.y]=='*')
            {
                continue;
            }
            else if(temp.x==ex&&temp.y==ey&&temp.z==ez)
            {
                ans=temp.step;
                flag=1;
                return;
            }
            else if(map[temp.z][temp.x][temp.y]=='.'&&vis[temp.z][temp.x][temp.y]==0) 
            {//并且是没有标记的才能走,否则不能走! 错点1 
            	vis[temp.z][temp.x][temp.y]=1;
                a=temp;
            }
            else if(map[temp.z][temp.x][temp.y]=='.'&&vis[temp.z][temp.x][temp.y]==1)
            {
            	continue;
            }
        }
        for(int i=0;i<4;i++)
        {
            temp.x=a.x+dx[i];
            temp.y=a.y+dy[i];
            temp.z=a.z;//这一句千万别丢了!wa了N次! 错点2 
            temp.step=a.step+1;
            if(judge())
            {
                if(temp.x==ex&&temp.y==ey&&temp.z==ez)//
                {
                    ans=temp.step;
                    flag=1;
                    return;
                }
                vis[temp.z][temp.x][temp.y]=1;//
                q.push(temp);
            }
        }
    }
}
int main()
{
    int T;
    scanf("%d",&T);
    while(T--)
    {
        scanf("%d%d%d",&n,&m,&t);
        ans=INF;flag=0;
        for(int i=0;i<n;i++)
           {
               getchar();
           for(int j=0;j<m;j++)
           {
               
               scanf("%c",&map[0][i][j]);//
               if(map[0][i][j]=='P')//
               {
                   ex=i;ey=j;ez=0;
               }
           }
          }
          getchar();
           for(int i=0;i<n;i++)
           {
            getchar();
           for(int j=0;j<m;j++)
           {
               scanf("%c",&map[1][i][j]);
               if(map[1][i][j]=='P')
               {
                   ex=i;ey=j;ez=1;
               }
           } 
         }

        bfs();
        if(flag==1&&ans<=t)//这个时间能等于!错点3(题上有说明) 
            printf("YES\n");
        else
            printf("NO\n");
    }
    return 0;
}

 
 

版权声明:本文为博主原创文章,未经博主允许不得转载。

HDU 2102 A计划

标签:

原文地址:http://blog.csdn.net/dxx_111/article/details/47375653

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!