题目链接: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 !”
潘警官赶忙掏出光剑,向日天砍去。不料成为咸鱼王的日天已然是刀枪不入,毫发无损。面对强大的日天, Xiper 丝毫不慌,他示意潘警官在豪宅外守候,自己只身迎战。在 Xiper 的智商碾压之下,日天被诱入火海之中。被火焰包围的日天发出一阵阵的惨叫声,怕是药丸。现在,已经打败了日天的 Xiper 要尽快逃出这间在熊熊燃烧的祖传豪宅。为了简化问题,我们将房子简化成一个 N 层楼,每层楼对应一个 L 行 R 列的网格图,并用不同的字符表示每个格点的状态。
-
. —— 表示该位置为空。 x —— 表示该位置上有障碍,不能移动。 U —— 表示上楼的楼梯入口。 D —— 表示下楼的楼梯入口。 X —— 表示 Xiper 现在所在的位置。 Y —— 表示 Xiper 要到达的出口的位置,保证在第一层楼的边界上。
每秒 Xiper 可以向前后左右移动一格,或者从楼梯的入口到对应的出口。 Xiper 不能移动到边界外的地方,也不能移动到障碍上。保证顶楼没有上楼入口,底层没有下楼入口,每个下楼入口对应的出口只会是上楼入口或者障碍,反之亦然。一个上楼入口只会对应一个下楼入口,且所在层数相邻,所处的行和列一致,反之亦然。注意,同一层楼可能存在多个楼梯;当楼梯入口对应的出口被障碍堵住时, Xiper 就无法到达出口的位置了。现在 Xiper 想知道,他最少要用多少时间能逃出来?
Input
第一行三个数字 N , L , R(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 55
char 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;
}