POJ 2251-Dungeon Master(三维BFS)

Dungeon Master

Time Limit: 1000MS Memory Limit: 65536K
Total Submissions: 68867 Accepted: 24888

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!

您被困在3D地牢中,需要找到最快的出路!地牢由可能填充或未填充岩石的单位立方体组成。向北,向南,向东,向西,向上或向下移动一个单元需要一分钟。您不能沿对角线移动,迷宫四面都是坚固的岩石。

有可能逃脱吗?如果是,需要多长时间?
输入值
输入包含多个地牢。每个地牢描述都以包含三个整数L,R和C(大小均限制为30)的行开头。
L是组成地牢的层数。
R和C是组成每个级别计划的行数和列数。
然后将出现R行的L个块,每个块包含C个字符。每个角色描述一个地牢单元。充满岩石的单元格用“#”表示,空单元格用“。”表示。您的起始位置以“ S”表示,出口以字母“ E”表示。每个级别之后只有一个空白行。输入以L,R和C的三个零终止。
输出量
每个迷宫产生一行输出。如果有可能到达出口,请打印表格的一行
Escaped in %d minute(s).

其中x替换为最短逃生时间。
如果无法逃脱,请打印该行
Trapped!!

题目链接

这是POJ的一道广搜题,和以前做过广搜题不同的是,题目给的是一个三维空间,并且方向扩展为6个,可以通过传送门逃脱,所以这是一个考查三维广搜的题,我们把之前存放地图的二维字符数组改成三维,方向增加为6个即可,唯一注意的细节是层数与层数之间有一空行,我们用getchar()吃掉回车就可以,然后对入口进行搜索,如果能走到E则输出最短时间,如果走不出去则输出被困,用普通广搜模板写代码就可以。AC代码:

#include <cstdio>
#include <iostream>
#include <algorithm>
#include <cstring>
#include <stack>
#include <queue> 
using namespace std;
const int _max=40;
const int mmax=3e5+50;
char m[_max][_max][_max];
int book[_max][_max][_max];//标记这个点是否走过
int l,r,c,step;
bool flag;
struct node{int x,y,z,s;};//定义队列存放的结构体元素
int main()
{
	void bfs(int,int,int);
	while(cin>>l>>r>>c)
	{
		if(l==0&&r==0&&c==0)
		  break;
		memset(book,0,sizeof(book));
		step=0;
		flag=false;
		for(int i=0;i<l;i++)
		{
		  for(int j=0;j<r;j++)
		    cin>>m[i][j];
		    getchar();
		}   
		for(int i=0;i<l;i++)
		  for(int j=0;j<r;j++)
		    for(int k=0;k<c;k++)
		    if(m[i][j][k]=='S')
			{
				bfs(i,j,k);//遍历地图找到人后开始搜
				break;
			}
		if(flag)
		  printf("Escaped in %d minute(s).\n",step);
		else
		  printf("Trapped!\n");	
	}
	return 0;
}
void bfs(int x,int y,int z)
{
	queue<node >q;
	int nx,ny,nz;
	int next[6][3]={{1,0,0},{-1,0,0},{0,1,0},{0,0,1},{0,-1,0},{0,0,-1}};
	struct node a;
	a.x=x;
	a.y=y;
	a.z=z;
	a.s=0;
	q.push(a);//人入队
	book[x][y][z]=1;
	while(q.empty()!=1)
	{
		for(int k=0;k<6;k++)
		{
			nx=q.front().x+next[k][0];
			ny=q.front().y+next[k][1];
			nz=q.front().z+next[k][2];
			if(nx<0||nx>l-1||ny<0||ny>r-1||nz<0||nz>c-1)
			  continue;
			if((m[nx][ny][nz]=='.'||m[nx][ny][nz]=='E')&&book[nx][ny][nz]==0)
			{
				book[nx][ny][nz]=1;
				a.x=nx;
				a.y=ny;
				a.z=nz;
				a.s=q.front().s+1;
				q.push(a);
			}
			if(m[nx][ny][nz]=='E')
			{
				flag=true;
				break;
			}
		}
		if(flag)
		  break;
		q.pop();
	}
	if(flag)
	  step=q.back().s;
	return;  
}

一年以后重新写了下此题 当时的码风好奇特T.T

#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cstring>
#include <cmath>
#include <map>
#include <vector>
#include <queue>

using namespace std;

typedef long long LL;
typedef pair<int, int> PII;
typedef tuple<int, int, int> TP;

const int N = 35;
const int INF = 0x3f3f3f3f;

int l, r, c;
char g[N][N][N];
int d[N][N][N];
TP tp1, tp2;
int dir[][3] = {{1, 0, 0}, {-1, 0, 0}, {0, 1, 0}, {0, 0, 1}, {0, -1, 0}, {0, 0, -1}};

void bfs() {
    memset(d, 0x3f, sizeof d);
    d[get<0>(tp1)][get<1>(tp1)][get<2>(tp1)] = 0;

    queue<TP > Q;
    Q.push(tp1);

    while (!Q.empty()) {
        TP t = Q.front();
        Q.pop();
        
        for (int i = 0; i < 6; i ++) {
            int nx = get<0>(t) + dir[i][0];
            int ny = get<1>(t) + dir[i][1];
            int nz = get<2>(t) + dir[i][2];
            
            if (nx < 1 || nx > l || ny < 1 || ny > r || nz < 1 || nz > c || g[nx][ny][nz] == '#' || d[nx][ny][nz] != INF) continue;
            Q.push({nx, ny, nz});
            d[nx][ny][nz] = d[get<0>(t)][get<1>(t)][get<2>(t)] + 1;
        }
    }
    
    return;
}

int main() {
    while (cin >> l >> r >> c) {
        if (!l || !r || !c) break;
        
        for (int i = 1; i <= l; i ++) {
            for (int j = 1; j <= r; j ++)
                scanf("%s", g[i][j] + 1);
        }

        for (int i = 1; i <= l; i ++)
            for (int j = 1; j <= r; j ++)
                for (int k = 1; k <= c; k ++)
                    if (g[i][j][k] == 'S') tp1 = {i, j, k};
                    else if (g[i][j][k] == 'E') tp2 = {i, j, k};
                    
        bfs();
        
        printf(d[get<0>(tp2)][get<1>(tp2)][get<2>(tp2)] == INF ? "Trapped!" : "Escaped in %d minute(s).", d[get<0>(tp2)][get<1>(tp2)][get<2>(tp2)]);
        puts("");
    }

    return 0;
}
posted @ 2020-02-29 11:07  Hayasaka  阅读(80)  评论(0编辑  收藏  举报