POJ 2251 Dungeon Master【广度优先搜索】


Dungeon Master
Time Limit: 1000MS Memory Limit: 65536K
Total Submissions: 44840 Accepted: 16880

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!

Source

题意:给你一个三维空间,起始点为‘S’,终点为‘E’。每个点只能在上下左右前后六个方向移动,只有遇到'.'时表示改点可以走,'#'表示岩石,不能走。问你从起始点‘S’到终点‘E’最少需要走的步数。

解题思路:1.先把起点入队列,并标记该点已经被访问过,

2.当队列不为空时,依次取队首元素,把每一个点周围的六个方向都遍历一遍,加到队列中去,并且把vis标记数组的值给改变,且 每一走的步数,都为上一次走的步数加一,即vis[i]=vis[i-1]+1;

3.循环2,直到遇见‘E’结束,或者队列为空为止。

题解:

#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<cmath>
#include<iostream>
#include<algorithm>
#include<queue>
using namespace std;
int L,R,C;
int vis[35][35][35];
char MAP[35][35][35];
///X Y Z数组为六个方向
int X[7]= {0,1,-1,0,0,0,0};
int Y[7]= {0,0,0,1,-1,0,0};
int Z[7]= {0,0,0,0,0,1,-1};
struct point
{
    int x;
    int y;
    int z;
};
point xyz(int x,int y,int z)///把对应的点转化为结构体point
{
    point m;
    m.x=x;
    m.y=y;
    m.z=z;
    return m;
}
queue<point>q;
void bfs(int x,int y,int z)
{
    point t;
    t.x=x;
    t.y=y;
    t.z=z;
    vis[x][y][z]=1;
    q.push(t);
    while(!q.empty())
    {
        point head=q.front();
        q.pop();
        if(MAP[head.x][head.y][head.z]=='E')///到达'E'出口,就退出
        {
            printf("Escaped in %d minute(s).\n",vis[head.x][head.y][head.z]-1);///把'S'点记录为第一步,所以减一
            return ;
        }
        for(int i=1; i<=6; i++)
        {
            int xx=head.x+X[i];
            int yy=head.y+Y[i];
            int zz=head.z+Z[i];
            if(xx<1||yy<1||zz<1||xx>L||yy>R||zz>C)
                continue;
            else
                if(vis[xx][yy][zz]==0&&MAP[xx][yy][zz]!='#')
                {
                   vis[xx][yy][zz]=vis[head.x][head.y][head.z]+1;///每一次遍历一次都为上一次步数加一

                   q.push(xyz(xx,yy,zz));
                }
            }

            }
            printf("Trapped!\n");
        }
int main()
{
    while(~scanf("%d %d %d",&L,&R,&C))
    {
        if(L==0&&R==0&&C==0)
            break;
        memset(vis,0,sizeof(vis));
        memset(MAP,0,sizeof(MAP));
        int x,y,z;
        for(int i=1; i<=L; i++)
            for(int j=1; j<=R; j++)
                for(int k=1; k<=C; k++)
                {
                    cin>>MAP[i][j][k];
                     if(MAP[i][j][k]=='S')
                    {
                        x=i;
                        y=j;
                        z=k;
                    }
                }
                    while(!q.empty()) q.pop();///清空队列
                    bfs(x,y,z);
    }
    return 0;
}



阅读更多
想对作者说点什么?

博主推荐

换一批

没有更多推荐了,返回首页