2016 UESTC Training Search Algorithm and StringB - Xiper的奇妙历险(2)(三维迷宫)

来源:互联网 发布:unity 删除数组 编辑:程序博客网 时间:2024/05/17 02:50

题目链接:http://acm.uestc.edu.cn/#/contest/show/99

B - Xiper的奇妙历险(2)

Time Limit: 3000/1000MS (Java/Others)     Memory Limit: 65535/65535KB (Java/Others)

转眼间,已经过了10年。Xiper和日天都以优异的成绩,从UESTC毕业了。毕业之后,Xiper每天勤奋地写代码。然而不知为何,Xiper总觉得自己的智商越来越低了。久而久之,Xiper对日天产生了怀疑。经过的一番调查,Xiper发现日天竟然在程序里下毒!日天面对Xiper和前来拘留他的潘警察,假意痛哭流涕,并要求Xiper亲手给带上手铐。然而就在Xiper准备给日天带上手铐时,日天微微一笑,竟从背后掏出了一条咸鱼!“我不做人啦,Xiper!”

title

潘警官赶忙掏出光剑,向日天砍去。不料成为咸鱼王的日天已然是刀枪不入,毫发无损。面对强大的日天,Xiper丝毫不慌,他示意潘警官在豪宅外守候,自己只身迎战。在Xiper的智商碾压之下,日天被诱入火海之中。被火焰包围的日天发出一阵阵的惨叫声,怕是药丸。现在,已经打败了日天的Xiper要尽快逃出这间在熊熊燃烧的祖传豪宅。为了简化问题,我们将房子简化成一个N层楼,每层楼对应一个LR列的网格图,并用不同的字符表示每个格点的状态。

  • .—— 表示该位置为空。x—— 表示该位置上有障碍,不能移动。U—— 表示上楼的楼梯入口。D—— 表示下楼的楼梯入口。X—— 表示Xiper现在所在的位置。Y—— 表示Xiper要到达的出口的位置,保证在第一层楼的边界上。

每秒Xiper可以向前后左右移动一格,或者从楼梯的入口到对应的出口。Xiper不能移动到边界外的地方,也不能移动到障碍上。保证顶楼没有上楼入口,底层没有下楼入口,每个下楼入口对应的出口只会是上楼入口或者障碍,反之亦然。一个上楼入口只会对应一个下楼入口,且所在层数相邻,所处的行和列一致,反之亦然。注意,同一层楼可能存在多个楼梯;当楼梯入口对应的出口被障碍堵住时,Xiper就无法到达出口的位置了。现在Xiper想知道,他最少要用多少时间能逃出来?

Input

第一行三个数字NLR(1<=N,L,R<=50),表示豪宅的大小。接下来从第1层开始依次输入;对于每一层,用L行个长度为R的字符串表示该层的状态。

Output

如果可以到达,输出一个数STEP,表示所需最少的步数。否则输出1

这里的Xiper和日天都是UESTC校队的的成员,总是喜欢出一些带黑故事的题。。。

题意很好理解,一个典型的三维迷宫,途中设置了障碍,和上下楼梯口;但是请注意,到达楼梯口并不意味着一定上下楼;

迷宫问题找最短路优先考虑bfs,三维bfs只不过比二维的bfs多了两种状态转移方向而已,所以只要你入门了,会用bfs找最短路,不管是几维迷宫都可以搞定;

#include<bits/stdc++.h>using namespace std;#define MAXN 55char s[MAXN][MAXN][MAXN];int visit[MAXN][MAXN][MAXN];//记忆化数组 struct node{int n,l,r,step;}start;struct node2{int dl,dr;}dre[4];int n,l,r;int bfs(struct node start){int i;queue<node> q;q.push(start);//初始状态入队 while(!q.empty()){struct node x=q.front();q.pop();if(s[x.n][x.l][x.r]=='Y')return x.step;for(i=0;i<4;i++)//前后左右 {int nn=x.n;int ll=x.l+dre[i].dl;int rr=x.r+dre[i].dr;if(ll<l&&ll>=0&&rr<r&&rr>=0&&!visit[nn][ll][rr]&&s[x.n][ll][rr]!='x')//判断是否合法 {struct node y=x;y.step++;y.l=ll;y.r=rr;visit[nn][ll][rr]=1;q.push(y);}}if(s[x.n][x.l][x.r]=='U'&&s[x.n+1][x.l][x.r]!='x'&&!visit[x.n+1][x.l][x.r])//上楼 {struct node y=x;y.n++;y.step++;visit[y.n][y.l][y.r]=1;q.push(y);}else if(s[x.n][x.l][x.r]=='D'&&s[x.n-1][x.l][x.r]!='x'&&!visit[x.n-1][x.l][x.r])//下楼 {struct node y=x;y.n--;y.step++;visit[y.n][y.l][y.r]=1;q.push(y);}}return -1;}int main(){int i,j,k,flag=1;char ch;scanf("%d%d%d",&n,&l,&r);memset(visit,0,sizeof(visit));dre[0].dl=0;//方向数组 dre[0].dr=1;dre[1].dl=1;dre[1].dr=0;dre[2].dl=-1;dre[2].dr=0;dre[3].dl=0;dre[3].dr=-1;for(i=0;i<n;i++){for(j=0;j<l;j++){scanf("%s",s[i][j]);for(k=0;k<r&&flag;k++){if(s[i][j][k]=='X'){start.n=i;start.l=j;start.r=k;start.step=0;flag=0;break;}}}}visit[start.n][start.l][start.r]=1;printf("%d",bfs(start));return 0;}


0 0