[POJ] 2251地牢大师 原创

来源:《信息学奥赛一本通》 , 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;
}
posted @ 2023-09-17 23:37  俺叫西西弗斯  阅读(0)  评论(0)    收藏  举报  来源