【题目链接】
ybt 1248:Dungeon Master
OpenJudge NOI 2.5 1253:Dungeon Master
【题目翻译】
地牢城主
描述
你被困在一个3D地牢中,需要找到可以走出地牢的最快的一条路。地牢由方块单位组成,方块中可能有或没有填满岩石。向东、南、西、北、上或下移动一个单位需要花费1分钟。你不可以向对角线方向移动。整个迷宫外各个方向都被坚硬的岩石包围。
是否可能逃脱呢?如果可能,需要用多久?
输入
输入包括一个地牢数字。每个地牢以包括L,R与C(大小都小于等于30)三个整数的一行开始。
L是地牢的层数。
R与C是每层平面的行数和列数。
接下来是L块,每块有R行,每行C个字符。每个字符表示一个地牢的房间。一个装满岩石的房间由’#‘表示,空房间由’.‘表示。你的起始位置由’S’表示,出口是字母’E’。每一层后有一个空行。
输入以表示L、R与C的三个0为结尾。
输出
每个迷宫产生一行输出。如果可能到达出口,如下面的格式输出一行:
Escaped in x minute(s).
x由逃离地牢所花费的最短时间代替
如果不可能逃离地牢,输出一行:
Trapped!
样例输入
3 4 5
S…
.###.
.##…
###.#
##.##
##…
#.###
####E
1 3 3
S##
#E#
0 0 0
样例输出
Escaped in 11 minute(s).
Trapped!
来源
Ulm Local 1997
【题目考点】
1. 搜索 迷宫问题
【解题思路】
二维迷宫问题可以参考:1251:仙岛求药
该题为三维迷宫问题,解题方法与二维迷宫问题类似,只需要将设的地图数组、vis数组变为三维、结点中表示坐标的变量设为三个。起点、终点坐标都是三维的,移动方向变为东西南北上下6个方向。
注意:
- 多组数据问题,要做数据清空。
- 输入数据时,先按层遍历,而后按行、按列遍历。要清楚三维数组第1、2、3维分别对应什么。
【题解代码】
解法1:广搜
#include<bits/stdc++.h>
using namespace std;
#define N 35
char mp[N][N][N];//地图 (x,y,z):x行y列z层
int l, r, c, ans;//l:层数 r:行数 c:列数
int sx, sy, sz, ex, ey, ez;//(sx,sy,sz):起点位置 (ex,ey,ez):终点位置
int dir[6][3] = {{0,0,1},{0,0,-1},{0,1,0},{0,-1,0},{1,0,0},{-1,0,0}};//方向数组
bool vis[N][N][N];//vis[i][j][k]:(i,j,k)位置是否已经访问过
struct Node
{
int x, y, z, t;//走到位置:(x,y,z),时间t
Node(){}
Node(int a, int b, int c, int d):x(a),y(b),z(c),t(d){}
};
int bfs()//从(sx,sy,sz)出发进行广搜,如果能到达终点(ex,ey,ez),返回时间。否则返回-1
{
queue<Node> que;
vis[sx][sy][sz] = true;
que.push(Node(sx, sy, sz, 0));
while(que.empty() == false)
{
Node u = que.front();
que.pop();
if(u.x == ex && u.y == ey && u.z == ez)
return u.t;
for(int i = 0; i < 6; ++i)
{
int x = u.x + dir[i][0], y = u.y + dir[i][1], z = u.z + dir[i][2];
if(x >= 1 && x <= r && y >= 1 && y <= c && z >= 1 && z <= l && vis[x][y][z] == false && mp[x][y][z] != '#')
{
vis[x][y][z] = true;
que.push(Node(x, y, z, u.t+1));
}
}
}
return -1;
}
int main()
{
while(cin >> l >> r >> c)
{
if(l == 0 && r == 0 && c == 0)
break;
for(int z = 1; z <= l; ++z)//层
for(int x = 1; x <= r; ++x)//行
for(int y = 1; y <= c; ++y)//列
{
cin >> mp[x][y][z];
if(mp[x][y][z] == 'S')
sx = x, sy = y, sz = z;
else if(mp[x][y][z] == 'E')
ex = x, ey = y, ez = z;
}
memset(vis, 0, sizeof(vis));
ans = bfs();//求到达终点的时间
if(ans == -1)
cout << "Trapped!" << endl;
else
cout << "Escaped in " << ans <<" minute(s)." << endl;
}
return 0;
}