zoukankan      html  css  js  c++  java
  • Dungeon Master

    Dungeon Master
    Time Limit:1000MS     Memory Limit:65536KB     64bit IO Format:%I64d & %I64u
    Submit Status

    Description

    You are trapped in a 3D dungeon and need to find the quickest way out! The dungeon is composed of unit cubes which may or may not be filled with rock. It takes one minute to move one unit north, south, east, west, up or down. You cannot move diagonally and the maze is surrounded by solid rock on all sides. 

    Is an escape possible? If yes, how long will it take? 

    Input

    The input consists of a number of dungeons. Each dungeon description starts with a line containing three integers L, R and C (all limited to 30 in size). 
    L is the number of levels making up the dungeon. 
    R and C are the number of rows and columns making up the plan of each level. 
    Then there will follow L blocks of R lines each containing C characters. Each character describes one cell of the dungeon. A cell full of rock is indicated by a '#' and empty cells are represented by a '.'. Your starting position is indicated by 'S' and the exit by the letter 'E'. There's a single blank line after each level. Input is terminated by three zeroes for L, R and C.

    Output

    Each maze generates one line of output. If it is possible to reach the exit, print a line of the form 
    Escaped in x minute(s).

    where x is replaced by the shortest time it takes to escape. 
    If it is not possible to escape, print the line 
    Trapped!

    Sample Input

    3 4 5
    S....
    .###.
    .##..
    ###.#
    
    #####
    #####
    ##.##
    ##...
    
    #####
    #####
    #.###
    ####E
    
    1 3 3
    S##
    #E#
    ###
    
    0 0 0
    

    Sample Output

    Escaped in 11 minute(s).
    Trapped!


    在一个3维空间里,从某一个开始位置走到一个结束位置,绕过有墙的位置,问是否可以走到,如果可以,需要几步。
    当然一步步走,一个位置包含4个信息:3个位置变量,一个走到这个位置所需step,用结构体存储。实现走路用了队列,while一直走, 遇E,over。
    #include<iostream>
    #include<algorithm>
    #include<cstring>
    #include<cstdio>
    #include<queue>
    
    using namespace std;
    
    #define maxn 100
    
    struct point
    {
        int x, y, z, step;
    };
    
    int sx, sy, sz, ex, ey, ez;
    int A, B, C, t;
    char maps[maxn][maxn][maxn];
    //int dir[6][3] = {{0,0,1},{0,0,-1},{0,1,0},{0,-1,0},{1,0,0},{-1,0,0}};
    int dir[6][3] = { 0,0,1,0,0,-1,0,1,0,0,-1,0,1,0,0,-1,0,0}; // 和上一句话意思一样都是表示要走的上下左右前后六个方向
    bool visit[maxn][maxn][maxn];
    
    int BFS();
    
    int main()
    {
        int i, j, q, ans;
    
        while(scanf("%d%d%d", &A, &B, &C), A+B+C)
        {
    
            for(i = 0; i < A; i++)
                for(j = 0; j < B; j++)
                    for(q = 0; q < C; q++)
                    {
                        cin >> maps[i][j][q];
                        if(maps[i][j][q] == 'S')
                        {
                            sx = i, sy = j, sz = q;  // 记录开始位置
                        }
                        if(maps[i][j][q] == 'E')
                        {
                            ex = i, ey = j, ez = q;   // 存储结束坐标点
                        }
                    }
    
    
                    ans = BFS();  // BFS返回需要多少步
    
                    if(ans == -1)
                        printf("Trapped!
    ");
                    else
                        printf("Escaped in %d minute(s).
    ", ans);
        }
        return 0;
    }
    
    int BFS()
    {
        point p, pn;    // 定义两个point结构体存储当前位置和下一步要走的位置
        queue<point> Q;   // 用队列存储要走的位置
    
        p.x = sx;   
        p.y = sy;
        p.z = sz;
    
        p.step = 0;
    
        Q.push(p);  // p表示当前位置点,也是开始点,第一个入队列
        memset(visit, false, sizeof(visit));  // 把标志数组全部置为flase,表示所有位置还没走过
    
        visit[sx][sy][sz] = true;  // 第一个位置置为true 表示已经走过
    
        while(!Q.empty())   // 只要队列里边有数就一直循环判断
        {
            p = Q.front();  //  把队列里边的数取出来
            Q.pop();  // 每一次取数后都有这个东西,释放?什么东西
    
            if(p.x == ex && p.y == ey && p.z == ez)
                return p.step;   //如果当前p位置是E,结束函数返回所需步数
    
            for(int i = 0; i < 6; i++)  // 6个方向,都要走
            {
                pn.x = p.x + dir[i][0];
                pn.y = p.y + dir[i][1];
                pn.z = p.z + dir[i][2];
    
                pn.step = p.step + 1;  // 走一个方向,那个方向的step+1,
    
                if(pn.x >= 0 && pn.x < A && pn.y >= 0 && pn.y < B && pn.z >= 0 && pn.z < C && (maps[pn.x][pn.y][pn.z] != '#') && !visit[pn.x][pn.y][pn.z])
                {
                    visit[pn.x][pn.y][pn.z] = true;   
                    Q.push(pn);  // 如果当前位置没有走过,可以走,在范围内,就把该位置入队列,把当前位置置为已经走过
                } 
            }
        }
        return -1;  // 如果走不到E位置,就返回-1;
    }
    让未来到来 让过去过去
  • 相关阅读:
    白天写代码,晚上摆地摊!9年前摆地摊学会了这些道理...
    啪啪,打脸了!领导说:try-catch必须放在循环体外!
    阿里巴巴为什么让初始化集合时必须指定大小?
    永远不要使用双花括号初始化实例,否则就会OOM!
    限流的6大狠招,附详细代码和评测结果
    HashMap 的 7 种遍历方式与性能分析!(强烈推荐)
    String性能提升10倍的几个方法!(源码+原理分析)
    9个小技巧让你的 if else看起来更优雅
    用了自定义Banner后,SpringBoot瞬间变的高大上了...
    别再问我 new 字符串创建了几个对象了!我来证明给你看!
  • 原文地址:https://www.cnblogs.com/Tinamei/p/4653555.html
Copyright © 2011-2022 走看看