一、题目描述
zjm被困在一个三维的空间中,现在要寻找最短路径逃生!
空间由立方体单位构成。
zjm每次向上下前后左右移动一个单位需要一分钟,且zjm不能对角线移动。
空间的四周封闭。zjm的目标是走到空间的出口。
是否存在逃出生天的可能性?如果存在,则需要多少时间?
Input
输入第一行是一个数表示空间的数量。
每个空间的描述的第一行为L,R和C(皆不超过30)。
L表示空间的高度,R和C分别表示每层空间的行与列的大小。
随后L层,每层R行,每行C个字符。
每个字符表示空间的一个单元。’#‘表示不可通过单元,’.‘表示空白单元。
zjm的起始位置在’S’,出口为’E’。每层空间后都有一个空行。
L,R和C均为0时输入结束。
Output
每个空间对应一行输出。
如果可以逃生,则输出如下
Escaped in x minute(s).
x为最短脱离时间。
如果无法逃生,则输出如下
Trapped!
Sample Input
3 4 5
S….
.###.
.##..
###.#
#####
#####
##.##
##…
#####
#####
#.###
####E
1 3 3
S##
#E#
###
0 0 0
Sample Outpu
Escaped in 11 minute(s).
Trapped!
二、思路概述
- 用一个三维数组记录迷宫信息,包括哪个位置是起点,哪个是终点,哪个位置不可以走,哪个位置可以通过。
- 从起点开始,进行bfs探索,遇到可以通过的位置以及它并未被走过,就压入队列,以便下一次探索,直到走到了终点的位置或者队列空(无法走到终点的位置),结束探索。
- 在point结构体中加一个level,用来表示层数,也就是走到某个位置走了几分钟。
三、细节
- 使用了队列queue,而且是多组输入输出,却没有考虑到队列要清零。
- 三维空间,判断坐标是否越界,明明数组是0-n-1(共n个数字),但是判断条件却写的是>n才越界,这个应该是属于,到底数组从0开始存储,还是从1开始的问题。
- int dx[]={0,0,0,0,1,-1};
int dy[]={0,0,1,-1,0,0};
int dz[]={1,-1,0,0,0,0};
使用这样的标记数组,往各个方向探索,我写的x=x+dx[i],应该是int xx=x+dx[i],不然的话,就是x这个点一直变化,非常诡异。
四、完整代码
/*可使用bfs的方法,从起点开始向上下左右四个方向探索,
如果可走,就进去,直到碰壁,或者不能走,直到走到终点*/
//可通过的块置0,不能的置1,起点置10,终点置100
#include<iostream>
#include<algorithm> //fill函数,sort函数,max函数
#include<set>//set函数,(去除重复)
#include<map>//不同类型转换
#include<cstring>//memset函数
#include<queue>
using namespace std;
struct point{
int x,y,z;
//bool is;
int level;
point(){}
point(int xx,int yy,int zz,int le)
{
x=xx;
y=yy;
z=zz;
level=le;
}
};
int l,r,c;
int kj[30][30][30];//三维数组,存储迷宫
int vis[30][30][30];//标记是否到达过
queue<point> xp;
int dx[]={0,0,0,0,1,-1};
int dy[]={0,0,1,-1,0,0};
int dz[]={1,-1,0,0,0,0};
void bfs(int xx,int yy,int zz){
for(int i=0;i<30;i++){
for(int j=0;j<30;j++){
for(int k=0;k<30;k++){
vis[i][j][k]=0;
}
}
}
point p(xx,yy,zz,0);
//p.is=true;
vis[xx][yy][zz]=1;
xp.push(p);
while(!xp.empty() ){
point pp=xp.front() ;xp.pop() ;
int px=pp.x;int py=pp.y;int pz=pp.z;int level=pp.level;
//cout<<px<<" "<<py<<" "<<pz<<"队列中点"<<endl;
if(kj[px][py][pz]==100){//找到了终点
cout<<"Escaped in "<<level<<" minute(s)."<<endl;
return ;
}
for(int i=0;i<6;i++){
int x=px+dx[i];int y=py+dy[i];int z=pz+dz[i];
//cout<<x<<" "<<y<<" "<<z<<" "<<vis[x][y][z]<<" "<<kj[x][y][z]<<endl;
if(x>=l||x<0||y>=r||y<0||z>=c||z<0)continue;
if(vis[x][y][z]==0&&kj[x][y][z]!=1){
vis[x][y][z]=1;
point pp1(x,y,z,level+1);
xp.push(pp1);
}
}
}
cout<<"Trapped!"<<endl;
}
int main(){
while(cin>>l>>r>>c){
while(!xp.empty() )xp.pop();
if(l==0&&r==0&&c==0)break;
int x,y,z;//起点的位置
for(int i=0;i<l;i++){
for(int j=0;j<r;j++){
for(int k=0;k<c;k++){
char c; cin>>c;
//cout<<c<<endl;
if(c=='.')kj[i][j][k]=0;
else if(c=='#')kj[i][j][k]=1;
else if(c=='S'){
kj[i][j][k]=10;
x=i;y=j;z=k;
}
else if(c=='E'){
kj[i][j][k]=100;
//cout<<i<<" "<<j<<" "<<k<<endl;
}
}
}
}
//cout<<111<<endl;
bfs(x,y,z);
}
}