Week12 作业 B - 必做题(三维空间迷宫)

一、题目描述

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,用来表示层数,也就是走到某个位置走了几分钟。

三、细节

  1. 使用了队列queue,而且是多组输入输出,却没有考虑到队列要清零。
  2. 三维空间,判断坐标是否越界,明明数组是0-n-1(共n个数字),但是判断条件却写的是>n才越界,这个应该是属于,到底数组从0开始存储,还是从1开始的问题。
  3. 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);
	}
} 
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值