Dungeon Master(三维迷宫求最短路径例题1)

Dungeon Master三维迷宫求最短路径例题1


其实本质和二维的图形并无太大差异

题目描述

题目链接
简单描述:
你被困在一个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!

题目分析

  1. 层数、行数、列数:我们要涉及到三维数组
    对于三维数组:我们只需要在二维数组上加一层循环即可。第一层循环为z轴(层数),第二层循环为x轴(行数), 第三层循环为y轴(列数)
  2. 求最短时间(即最短路径)用bfs
    上下前后左右:我们用的三个大小为6数组来表示对应坐标的变化。

代码

#include <iostream>
#include <algorithm>
#include <cstdio>
#include <queue>
#include <cstring>
using namespace std;
const int N = 33;
char q[N][N][N];
int book[N][N][N];
int l, r, d, ans;
int zz[] = {1, -1, 0, 0, 0, 0}, xx[] = {0, 0, -1, 0, 1, 0}, yy[] = {0, 0, 0, 1, 0, -1};

struct f{
    int z;
    int x;
    int y;
    int s;
};
queue <f> qu;


int bfs(int sz, int sx, int sy){
    struct f a;
    a.z = sz;
    a.x = sx;
    a.y = sy;
    a.s = 0;
    qu.push(a);
    book[sz][sx][sy] = 1;
    while(!qu.empty()){
        struct f b = qu.front();
        qu.pop();
        int k = 0;
        for(int i = 0; i < 6; i ++){
            struct f c;
            c.x = b.x + xx[i];
            c.z = b.z + zz[i];
            c.y = b.y + yy[i];
            c.s = b.s + 1;
            if(c.x < 0 || c.y < 0 || c.z < 0 || c.z >= l || c.x >= r || c.y >= d) continue;
            if(book[c.z][c.x][c.y] == 0 && q[c.z][c.x][c.y] != '#'){
                qu.push(c);
                book[c.z][c.x][c.y] = 1;
                if(q[c.z][c.x][c.y] == 'E'){
                   // ans = c.s;
                    return c.s;
                }
            }
        }

    }
    return -1;
}

int main(void){
    int sz, sx, sy;
    while(1){
        scanf("%d %d %d", &l, &r, &d);
        if(l == 0 && r == 0 && d == 0) return 0;
        for(int i = 0; i < l; i ++){
            for(int j = 0; j < r; j ++){
                for(int k = 0; k < d; k ++){
                    cin >> q[i][j][k];
                    if(q[i][j][k] == 'S'){
                        sz = i;
                        sx = j;
                        sy = k;
                    }
                }
            }
        }
       // ans = 0;

        ans = bfs(sz, sx, sy);
        if(ans >= 0) printf("Escaped in %d minute(s).\n", ans);
        else puts("Trapped!");
        while(qu.size()) qu.pop();
        memset(book, 0, sizeof(book));
    }
}


几个细节:

  1. 多组输入,记得memset标记数组。
  2. 因为涉及到三维,判断是否为合法坐标时,一定要按照顺序走,三个参数,不重不漏(粗心大意,找了半个多小时才看出来)
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Xuhx&

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值