hdu2102A计划

来源:互联网 发布:淘宝买东西怎么收货 编辑:程序博客网 时间:2024/06/15 02:42

题目看链接:

https://vjudge.net/problem/HDU-2102

大致思路:

本来是一个很基础的走迷宫找最短路径的问题,因为加了一个比较特殊的传送门之后,让这道题的判断条件出了一点变化。正常的迷宫无非就三种状态,能走,是石头,走过了。然而这里加了第四种状态——传送门。就将判断条件变复杂了。
首先:
1.初步筛选,看它是不是在迷宫的范围之内以及有没有走过。
2.进行大致筛选:三个分支:
一是正常的路(空地,以及有公主的地方
二不是正常的路,是传送门
三是墙走不通
3.进行最后的筛选
由于能不能走走传送门主要靠另一层的情况来决定:所以根据另一层的情况又有了分类:
一,因为另一层的该点有石头,或者是另一层的该点走过了,又或者是另一层的该点是一个传送门,走了之后会陷入死循环,所以不能走。
二,不属于以上的三种情况,说明还能走。

以下是代码:

#include <iostream>#include<cstring>#include<cstdio>#include<queue>#include<algorithm>#include<cmath>using namespace std;#define MAX 11char map[MAX][MAX][2];//地图bool vis[MAX][MAX][2];//标记int N,M,T;//N,M,Tint px,py,pz;//公主的位置int flag,t;//标记struct node{int x,y,z,step;};int dx[4]={1,-1,0,0};int dy[4]={0,0,-1,1};void bfs(){  memset(vis,0,sizeof(vis));  int i;  vis[0][0][0]=1;//这里必须要标记为1  node u,v;  u.x=0;  u.y=0;  u.z=0;//起点  u.step=0; queue<node> q; q.push(u); while(!q.empty()) {    u=q.front();    q.pop();   //找到了公主    if(u.x==px&&u.y==py&&u.z==pz)    {        flag=1;        t=u.step;        return;    }    //四个方向探寻    for(i=0;i<4;i++){    v.x=u.x+dx[i];    v.y=u.y+dy[i];    v.z=u.z;    //初步删选,两个条件,在边框内,还没走过    if(v.x>=0&&v.x<N&&v.y>=0&&v.y<M&&!vis[v.x][v.y][v.z])    {        //第一种情况能走,下一个点是公主的位置,或者下一个点是一个单纯的能走的位置即‘.’        if(map[v.x][v.y][v.z]=='.'||map[v.x][v.y][v.z]=='P')        {            v.step=u.step+1;            v.z=u.z;            vis[v.x][v.y][v.z]=1;            q.push(v);        }        //下一个是传送门        //这里又分为两种情况        //1.能经过传送门到达下一层        //2.到达下一层的该位置并不能走        else if(map[v.x][v.y][v.z]=='#')        {            int Z;            Z=(u.z+1)%2;            //已不能走的三个原因作为判断条件            //1.下一层中该位置:1.有墙2.走过了 3.有传送门(会陷入传送门的死循环)            if(map[v.x][v.y][Z]=='#'||map[v.x][v.y][Z]=='*'||vis[v.x][v.y][Z])            {                map[v.x][v.y][Z]='*';                map[v.x][v.y][v.z]='*';                //将这两个点封印为墙                //跳过这个点去下一层                continue;            }            else{                v.z=Z;                v.step=u.step+1;//这里step一定要加一                //因为走到上一层的这个位置要一个时间                q.push(v);                vis[v.x][v.y][v.z]=1;                }        }        //当为墙时自动跳过    }   } }return;}int main(){    int S;    cin>>S;//测试组数    int i,j,k;    while(S)    {        S--;        //初始化墙        memset(map,0,sizeof(map));        cin>>N>>M>>T;        for(i=0;i<2;i++)          for(j=0;j<N;j++)            for(k=0;k<M;k++)        {         cin>>map[j][k][i];         if(map[j][k][i]=='P')            px=j,py=k,pz=i;        }//输入墙并找到公主        flag=0;        bfs();        //能就下公主的条件        if(flag==1&&t<=T)            cout<<"YES"<<endl;        else//否则不能救下公主            cout<<"NO"<<endl;    }    return 0;}//理解题意当到达了传送门的坐标的时候//必定传送//骑士们一进入时空传输机就会被转到另一层的相对位置//不能跳过传送门到达该层的另一个空地//回避传送门的条件//1.传送到的另一层的相对位置是一个墙//2.传送到的相对位置也是一个传送门无限传送//3.传送到的相对位置已经走过了//到了传送门如果满足条件立即前往另一层