、##题目链接:
http://acm.nyist.net/JudgeOnline/problem.php?pid=353
描述
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?
输入
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.
输出
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!
样例输入
3 4 5 S…. .###. .##.. ###.#
|
样例输出
Escaped in 11 minute(s). Trapped! |
题目中文描述
简单翻译就是输入三维矩阵,第一行是L,R,C,分别代表着层数、每一层的行和列的数目。然后有L个R*C的矩阵,其中S代表起始点,E代表结束点,.代表可以走的路,#代表墙,问从S到E最少需要多少步。如果不能达到E,则输出Trapped!,如果可以,输出Escaped in # minute(s).(其中#代表最少需要的步数)
算法思想:
这道题是一道简单的广度搜索,只不过把一般的二维的扩展到了三维,算法思想其实是一样的,当然深度搜索也是可以的,但是会超时。由于前面AC过一道最少步数的题目(二维的),所以使用了深度搜索,结果超时,后来使用广度搜索,内存却超了,改进代码AC通过。
广度搜索的思想很简单,就是从起始结点开始搜索其相邻的六个方向(当然边界也需判断),如果遇到E,则退出,并返回步数,否则将其进队列,并将其标记为已访问。以此类推,直到队列为空。
深度搜索更简单,搜索当前点的六个方向,并更新当前点的状态为 ‘#’,表示已访问过,设为墙,注意搜索完后需要回溯,即将当前点的状态更新回来。
深搜源代码(超时)
/*
NYOJ(353):3D dungeon
Author:YangLinfeng
深度遍历
*/
#include <iostream>
#include <cstring>
#include <algorithm>
using namespace std;
int L, R, C, cnt;
char map[35][35][35];
typedef struct{
int l, r, c;
}Node,*PNode;
Node start;
void dfs(int x,int y,int z,int s)
{
if (map[x][y][z] == '#' || map[x][y][z] == 0) return;//第一种退出条件
if (map[x][y][z] == 'E')//第二种退出条件
{
cnt = min(cnt,s);
return;
}
s++;
map[x][y][z] = '#';//做标记,表示已访问
dfs(x + 1, y, z, s);
dfs(x - 1, y, z, s);
dfs(x, y + 1, z, s);
dfs(x, y - 1, z, s);
dfs(x, y, z + 1, s);
dfs(x, y, z - 1, s);
map[x][y][z] = '.';//回溯
}
int main()
{
while (cin >> L >> R >> C && L + R + C)
{
memset(map,0,sizeof(map));
cnt = 9999999;
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')
start.l = i, start.r = j, start.c = k;
}
}
}
dfs(start.l,start.r,start.c,0);
if (cnt != 9999999)
{
cout << "Escaped in " << cnt << " minute(s)." << endl;
}
else
cout << "Trapped!" << endl;
}
return 0;
}
广搜源代码
/*
Author:YangLinfeng
NYOJ(353):3D dungeon
广度优先
*/
#include <iostream>
#include <algorithm>
#include <cstring>
#include <queue>
using namespace std;
char map[35][35][35];
int dir[6][3] = { { 0, 1, 0 }, { 0, 0, 1 }, { 0, -1, 0 }, { 0, 0, -1 }, { -1, 0, 0 }, { 1, 0, 0 } }; //六个方向
typedef struct{
int l, r, c, step;
}Node, *PNode;
int visited[35][35][35]; //标记数组
queue<Node> Q;
Node e, curr;
int bfs(Node node)
{
while (!Q.empty()) Q.pop();
Q.push(node);
while (!Q.empty())
{
e = Q.front();
Q.pop();
visited[e.l][e.r][e.c] = 1;
//把e点相邻的六个方向且满足条件的点添加值队列中
for (int i = 0; i < 6; i++)
{
int l, r, c;
l = e.l + dir[i][0], r = e.r + dir[i][1], c = e.c + dir[i][2];
if (!visited[l][r][c] && map[l][r][c] != '#' && map[l][r][c] != 0)
{
curr = { l, r, c, e.step + 1 };
//当当前点是E点,退出(退出的第一种条件)
if (map[curr.l][curr.r][curr.c] == 'E')
{
return curr.step;
}
visited[curr.l][curr.r][curr.c] = 1;
Q.push(curr);
}
}
}
//当队列为空,表示搜索了所有路径还未找到E点,E点不可达,退出(退出的第二种条件)
return -1;
}
int main()
{
int L, R, C;
Node start;
while (cin >> L >> R >> C && (L + R + C))
{
memset(map, 0, sizeof(map)), memset(visited,0,sizeof(visited));
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')
start.l = i, start.r = j, start.c = k, start.step = 0;
}
}
}
int ret = bfs(start);
if (ret == -1)
cout << "Trapped!" << endl;
else
cout << "Escaped in " << ret << " minute(s)." << endl;
}
return 0;
}