Dungeon Master

Description - 题目描述
  你被困在一个3D地牢中且继续寻找最短路径逃生!地牢由立方体单位构成,立方体单位中有的会充满岩石。向上下前后左右移动一个单位需要一分钟。你不能向对角线的四个方向移动且迷宫四周环绕着许多岩石。

是否可以逃出地牢?如果可以,则需要多少时间?
Input - 输入
  输入的第一行包含一个数,表示地牢的数量。
  每个地牢的描述,其第一行包含三个数L,R和C(均小于等于30)。
  L表示地牢的层数;R和C分别表示每层地牢的行与列的大小。

随后输入地牢的层数L,每层中包含R行,每行中包含C个字符。
  每个字符表示地牢的一个单元。’#‘表示岩石单元,’.‘表示空白单元。你的起始位置在点’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 Output - 输出样例
Escaped in 11 minute(s).
Trapped!Description - 题目描述
  你被困在一个3D地牢中且继续寻找最短路径逃生!地牢由立方体单位构成,立方体单位中有的会充满岩石。向上下前后左右移动一个单位需要一分钟。你不能向对角线的四个方向移动且迷宫四周环绕着许多岩石。

是否可以逃出地牢?如果可以,则需要多少时间?
Input - 输入
  输入的第一行包含一个数,表示地牢的数量。
  每个地牢的描述,其第一行包含三个数L,R和C(均小于等于30)。
  L表示地牢的层数;R和C分别表示每层地牢的行与列的大小。

随后输入地牢的层数L,每层中包含R行,每行中包含C个字符。
  每个字符表示地牢的一个单元。’#‘表示岩石单元,’.‘表示空白单元。你的起始位置在点’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 Output - 输出样例
Escaped in 11 minute(s).
Trapped!

注:
方法:queue队列加广搜(bfs)可以用扇形区域来理解,每次都一层一层向外扩散,像扇子一样,先出队列且为目标位置的点一定是最短路径到达的。
注意地牢L.R.C分别表示什么
注意用广搜,深搜会超时
注意走过的路径要标记


#include <iostream>
#include <cstdio>
#include <queue>
#include <cstring>
using namespace std;
int L, R, C,ans;
//移动的方向:上下前后左右
int rode[6][3]={{1,0,0},{-1,0,0},{0,1,0},{0,-1,0},{0,0,1},{0,0,-1}};
char arr[40][40][40];//记录原始输入数据
struct node
{
    int x;
    int y;
    int z;
    int step;
} f, t;
int BFS(int az, int ax, int ay)
{
    queue <node> q;
    f.x = ax;
    f.y = ay;
    f.z = az;
    f.step = 0;
    q.push(f);
    while(!q.empty())
    {
        f = q.front();
        q.pop();
        int bx = f.x;
        int by = f.y;
        int bz = f.z;
        ans = f.step;
        for(int i=0; i<6; i++)
        {
            int nx = bx + rode[i][0];
            int ny = by + rode[i][1];
            int nz = bz + rode[i][2];
            //判断移动方向是否符合要求
            if(nx<0||nx>=R||ny<0||ny>=C||nz<0||nz>=L||arr[nz][nx][ny]=='#')
                continue;
            if(arr[nz][nx][ny]=='E')
                return ans+1;
                t.step = ans + 1;
                t.x = nx;
                t.y = ny;
                t.z = nz;
                q.push(t);
                //达到标记结点已入队的目的
                arr[t.z][t.x][t.y] = '#';
         }
    }
    return 0;
}
int main()
{
    int headx, heady, headz, i, j, k;
    //L层  R行 C列
    while(scanf("%d %d %d", &L, &R, &C)!=EOF&&L!=0&&R!=0&&C!=0)
    {
        for(i=0; i<L; i++)
        {
            for(j=0; j<R; j++)
            {
                scanf("%s", arr[i][j]);
                for(k=0; k<C; k++)
                {
                    //取起始点
                    if(arr[i][j][k]=='S')
                    {
                        headx = i;
                        heady= j;
                        headz = k;
                    }
                }
            }
        }
        ans = BFS(headx , heady , headz );
        if(ans)
            printf("Escaped in %d minute(s).\n", ans);
        else
            printf("Trapped!\n");
    }
    return 0;
}

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值