bfs

来源:互联网 发布:国际域名和国别域名 编辑:程序博客网 时间:2024/06/14 01:06

问题 G: 打败魔王

时间限制: 2 Sec  内存限制: 128 MB
提交: 65  解决: 10
[提交][状态][讨论版]

题目描述

可怜的公主又被魔王抓走了。魔王这次准备在T时刻与公主成亲,不过公主深信智勇的骑士CZY肯定能将她救出。
已知:公主被关在一个两层的迷宫里,迷宫的入口是S(0,0,0),公主的位置用P表示,时空传输机用#表示,墙用*表示,平地用.表示。
CZY一进入时空传输机就会被转到另一层的相对位置,但如果被转到的位置是墙的话,那CZY就会被撞死。
CZY在一层中只能前后左右移动,每移动一格花1时刻。层间的移动只能通过时空传输机,且不需要任何时间。

输入

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

输出

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

样例输入

1 4 2.#.#*.#P

样例输出

NO
 
思路:
    这道题和杭电A计划一模一样,就是这个是到文件结束,要是不会,去看杭电A计划!
代码:
 
//这道题整整花了我一天的时间!就是找不到错误,最终找到了三处错误的地方,在下面都标记过了/*这道题的思路和其他的广搜题大体一样,唯一的不同就是在上下的方向上有限制,所以你要在遇到#的 时候要另外讨论是上,还是下,还是死路一条,所以,在解这道题的时候,就只分前后左右就行了,在上下的时候应该在前后左右移动之前就得判断是否能上下,能上下移动的条件是所在的位置是#,并且#上面(或下面)的位置是点(.),并且之前没有走过这个位置!然后当你移动过之后,你应该将矛头转向移动过之后的点在它周围找终点;需要注意的是:当#上面(或者下面)是#或者是*号的时候,就只能思路一条了!也有可能就是终点,你就到终点了! */ #include <stdio.h>#include <string.h>#include <math.h>#include <queue>#include <algorithm>#define INF 0xfffffffusing 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;}

0 0
原创粉丝点击