Dungeon Master题解bfs

题面翻译

【题目描述】
这题是一个三维的迷宫题目,其中用‘.’表示空地,‘#’表示障碍物,‘S’表示起点,‘E’表示终点,求从起点到终点的最小移动次数,解法和二维的类似,只是在行动时除了东南西北移动外还多了上下。可以上下左右前后移动,每次都只能移到相邻的空位,每次需要花费一分钟,求从起点到终点最少要多久。

【输入】
多组测试数据。

一组测试测试数据表示一个三维迷宫:

前三个数,分别表示层数、一个面的长和宽,后面是每层的平面图。前三个数据为三个零表示结束。

【输出】
最小移动次数。

Translated by @剑圣夜雨声烦

题目描述

PDF

输入格式

输出格式

样例 #1

样例输入 #1

3 4 5
S....
.###.
.##..
###.#

#####
#####
##.##
##...

#####
#####
#.###
####E

1 3 3

S##
#E#
###

0 0 0

样例输出 #1

Escaped in 11 minute(s).
Trapped!

题解思路及TIME EXCEEDED问题

我最开始使用的方法和上一篇文章一样,采用的递归的思想,然而超时了……
所以转而使用循环来解决,超时的算法我就放在最后面了。
暴力搜索的循环写法可以类比图的bfs遍历搜索,使用一个队列来遍历整个图。每遍历到一个节点就把节点入队,遍历完队首所有邻接节点后队首出队。

题解


#include <cstdio>
#include <string.h>
#include <queue>
#include <limits.h>
using namespace std;

int l, r, c,mmin;
char map[50][50][50];
int vis[50][50][50];
typedef struct op
{
    int x;
    int y;
    int z;
    int step;
} point;

int judge(int x, int y ,int z)
{
    if (x < 0 || y < 0 || z < 0 || x >= l || y >= r || z >= c)
        return 0;
    if (map[x][y][z] == '#' || vis[x][y][z] == 1)
        return 0;
    return 1;
}

// 通过遍历矩阵来模拟移动,代码量很小
const int arrx[6] = {0, 0, 0, 0, 1, -1};
const int arry[6] = {0, 0, 1, -1, 0, 0};
const int arrz[6] = {1, -1, 0, 0, 0, 0};
void bfs(int x, int y, int z)
{
    queue<point> q;
    point buf;
    buf.x = x;
    buf.y = y;
    buf.z = z;
    buf.step = 0;
    q.push(buf);
    vis[x][y][z] = 1;
    while (!q.empty())
    {
        point cur = q.front();

        if (map[cur.x][cur.y][cur.z] == 'E')
        {
            if (cur.step < mmin)
            {
                mmin = cur.step;
            }
        }
        q.pop();
        //模拟移动,好好看好好学
        for (int i = 0; i < 6; i++)
        {
            int newx = cur.x + arrx[i];
            int newy = cur.y + arry[i];
            int newz = cur.z + arrz[i];
            if (judge(newx, newy, newz))
            {
                buf.x = newx;
                buf.y = newy;
                buf.z = newz;
                buf.step = cur.step + 1;
                vis[newx][newy][newz] = 1;
                q.push(buf);
            }
        }
    }

    return;
}
int main()
{

    while (scanf("%d %d %d", &l, &r, &c) && l != 0)
    {
        mmin = INT_MAX;
        point start;
        getchar();
        memset(vis, 0, sizeof(vis));
        for (int i = 0; i < l; i++)
        {
            if (i > 0)
                getchar();
            for (int j = 0; j < r; j++)
            {
                for (int k = 0; k < c; k++)
                {
                    scanf("%c", &map[i][j][k]);

                    if (map[i][j][k] == 'S')
                    {
                        start.x = i;
                        start.y = j;
                        start.z = k;
                    }
                    if (k == c - 1)
                    {
                        getchar();
                    }
                }
            }
        }
        // printf("********************\n");
        // for (int i = 0; i < l; i++)
        // {
        //     for (int j = 0; j < r; j++)
        //     {
        //         for (int k = 0; k < c; k++)
        //         {
        //             printf("%c ", map[i][j][k]);
        //             if (k == c - 1)
        //             {
        //                 printf("\n");
        //             }
        //         }
        //     }
        // }

        bfs(start.x, start.y, start.z);
        if (mmin == INT_MAX)
        {
            printf("Trapped!\n");
        }
        else
        {
            printf("Escaped in %d minute(s).\n", mmin);
        }
    }
    return 0;
}

超时题解(个人觉得没问题)

#include <cstdio>
#include <string.h>

#include <limits.h>
int count;
int l, r, c;
char map[50][50][50];
int
vis[50][50][50];
typedef struct op
{
    int x;
    int y;
    int z;
} point;
int max;
void dfs(int x, int y, int z)
{

    if (map[x][y][z] == 'E')
    {
        //        printf("i'm out!!\n");
        if (count < max && count != 0)
            max = count;
        return;
    }
    if (x - 1 >= 0)
    {
        if (map[x - 1][y][z] != '#' && vis[x - 1][y][z] == 0)
        {
            count++;
            vis[x][y][z] = 1;
            dfs(x - 1, y, z);
            vis[x][y][z] = 0;
            count--;
        }
    }
    if (y - 1 >= 0)
    {
        if (map[x][y - 1][z] != '#' && vis[x][y - 1][z] == 0)
        {
            count++;
            vis[x][y][z] = 1;
            dfs(x, y - 1, z);
            vis[x][y][z] = 0;
            count--;
        }
    }
    if (z - 1 >= 0)
    {
        if (map[x][y][z - 1] != '#' && vis[x][y][z - 1] == 0)
        {
            count++;
            vis[x][y][z] = 1;
            dfs(x, y, z - 1);
            vis[x][y][z] = 0;
            count--;
        }
    }
    if (x + 1 < l)
    {
        if (map[x + 1][y][z] != '#' && vis[x + 1][y][z] == 0)
        {
            count++;
            vis[x][y][z] = 1;
            dfs(x + 1, y, z);
            vis[x][y][z] = 0;
            count--;
        }
    }
    if (y + 1 < r)
    {
        char buf1 = map[x][y + 1][z];
        int buf2 = vis[x][y + 1][z];
        if (map[x][y + 1][z] != '#' && vis[x][y + 1][z] == 0)
        {
            count++;
            vis[x][y][z] = 1;
            dfs(x, y + 1, z);
            vis[x][y][z] = 0;
            count--;
        }
    }
    if (z + 1 < c)
    {
        if (map[x][y][z + 1] != '#' && vis[x][y][z + 1] == 0)
        {
            count++;
            vis[x][y][z] = 1;
            dfs(x, y, z + 1);
            vis[x][y][z] = 0;
            count--;
        }
    }
    return;
}
int main()
{

    while (scanf("%d %d %d", &l, &r, &c) && l != 0)
    {
        max = INT_MAX;
        point start;
        getchar();
        memset(vis, 0, sizeof(vis));
        for (int i = 0; i < l; i++)
        {
            if (i > 0)
                getchar();
            for (int j = 0; j < r; j++)
            {
                for (int k = 0; k < c; k++)
                {
                    scanf("%c", &map[i][j][k]);

                    if (map[i][j][k] == 'S')
                    {
                        start.x = i;
                        start.y = j;
                        start.z = k;
                    }
                    if (k == c - 1)
                    {
                        getchar();
                    }
                }
            }
        }
        //这是用来检查输入是否正确的
        // printf("********************\n");
        // for (int i = 0; i < l; i++)
        // {
        //     for (int j = 0; j < r; j++)
        //     {
        //         for (int k = 0; k < c; k++)
        //         {
        //             printf("%c ", map[i][j][k]);
        //             if (k == c - 1)
        //             {
        //                 printf("\n");
        //             }
        //         }
        //     }
        // }

        count = 0;
        dfs(start.x, start.y, start.z);
        if (max == INT_MAX)
        {
            printf("Trapped!\n");
        }
        else
        {
            printf("Escaped in %d minute(s).\n", max);
        }
    }
    return 0;
}
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值