来源:《信息学奥赛一本通》 , POJ 2251
算法标签 BFS
题目描述
你现在被困在一个三维地牢中,需要找到最快脱离的出路!
地牢由若干个单位立方体组成,其中部分不含岩石障碍可以直接通过,部分包含岩石障碍无法通过。
向北,向南,向东,向西,向上或向下移动一个单元距离均需要一分钟。
你不能沿对角线移动,迷宫边界都是坚硬的岩石,你不能走出边界范围。
请问,你有可能逃脱吗?
如果可以,需要多长时间?
输入格式
输入包含多组测试数据。
每组数据第一行包含三个整数 L,R,C 分别表示地牢层数,以及每一层地牢的行数和列数。
接下来是 L 个 R 行 C 列的字符矩阵,用来表示每一层地牢的具体状况。
每个字符用来描述一个地牢单元的具体状况。
其中, 充满岩石障碍的单元格用”#”表示,不含障碍的空单元格用”.”表示,你的起始位置用”S”表示,终点用”E”表示。
每一个字符矩阵后面都会包含一个空行。
当输入一行为”0 0 0”时,表示输入终止。
输出格式
每组数据输出一个结果,每个结果占一行。
如果能够逃脱地牢,则输出”Escaped in x minute(s).”,其中X为逃脱所需最短时间。
如果不能逃脱地牢,则输出”Trapped!”。
数据范围
1≤L,R,C≤100
输入样例:
3 4 5
S....
.###.
.##..
###.#
#####
#####
##.##
##...
#####
#####
#.###
####E
1 3 3
S##
#E#
###
0 0 0
输出样例:
Escaped in 11 minute(s).
Trapped!
思路
本题与一般的裸BFS仅区别于有三层,则三维数组,BFS找最短路径。
我们需要确认可移动方向为三维即dx[]={1,-1,0,0,0,0},dy[]={0,0,1,-1,0,0},dz[]={0,0,0,0,1,-1};
。
用BFS模板套即可。
C++ 代码
#include<iostream>
#include<cstdio>
#include<queue>
#include<cstring>
#include<algorithm>
using namespace std;
const int N=110;
int l,r,c;
struct node//因为是三维 所以不能用pair
{
int x,y,z;
};
char g[N][N][N];
int dist[N][N][N];//实际是statu+distance二合一了 用-1判断没走过
int dx[]={1,-1,0,0,0,0},dy[]={0,0,1,-1,0,0},dz[]={0,0,0,0,1,-1};//确定每一步有可能走的方向
int bfs(node st,node ed)
{
memset(dist,-1,sizeof dist);//把所有dist清为-1,作为没走过的标志
queue<node>q;//在函数内生成队列 因为要多次使用,所以需要局部的自动生成
dist[st.x][st.y][st.z]=0;//其实距离清空为0 方便下面的判断
q.push(st);//插入头
while(q.size())
{
node t = q.front();//拿到队列的头
q.pop();//排出头
for(int i=0;i<6;i++)//三维可能的方向
{
int x=t.x+dx[i],y=t.y+dy[i],z=t.z+dz[i];//载入当前位置
if(x<0||x>=l||y<0||y>=r||z<0||z>=c)continue;//防止越界 必须在第一行
else if(g[x][y][z]=='#')continue;//岩石 不可走
else if(dist[x][y][z]!=-1)continue;//!=-1即为走过,不走
dist[x][y][z]=dist[t.x][t.y][t.z]+1;//等于原始距离+1
if(ed.x==x&&ed.y==y&&ed.z==z)return dist[x][y][z];//到终点了就返回
q.push({x,y,z});//讲符合条件的放入队尾,以便BFS查找可能的位置
}
}
return -1;
}
int main()
{
while(cin>>l>>r>>c,l||r||c)//多个地图,当变量为0 0 0时 停止
{
node st,ed;
for(int i=0;i<l;i++)
for(int j=0;j<r;j++)
for(int k=0;k<c;k++)
{
cin>>g[i][j][k];//输入地图
if(g[i][j][k]=='E')ed={i,j,k};
else if(g[i][j][k]=='S')st={i,j,k};//找到开始与结束地点
}
if(bfs(st,ed)==-1)cout<<"Trapped!"<<endl;
else cout<<"Escaped in "<<bfs(st,ed)<<" minute(s)."<<endl;//输出答案
}
return 0;
}