题面翻译
【题目描述】
这题是一个三维的迷宫题目,其中用‘.’表示空地,‘#’表示障碍物,‘S’表示起点,‘E’表示终点,求从起点到终点的最小移动次数,解法和二维的类似,只是在行动时除了东南西北移动外还多了上下。可以上下左右前后移动,每次都只能移到相邻的空位,每次需要花费一分钟,求从起点到终点最少要多久。
【输入】
多组测试数据。
一组测试测试数据表示一个三维迷宫:
前三个数,分别表示层数、一个面的长和宽,后面是每层的平面图。前三个数据为三个零表示结束。
【输出】
最小移动次数。
Translated by @剑圣夜雨声烦
题目描述
输入格式
输出格式
样例 #1
样例输入 #1
3 4 5
S....
.###.
.##..
###.#
#####
#####
##.##
##...
#####
#####
#.###
####E
1 3 3
S##
#E#
###
0 0 0
样例输出 #1
Escaped in 11 minute(s).
Trapped!
题解思路及TIME EXCEEDED问题
我最开始使用的方法和上一篇文章一样,采用的递归的思想,然而超时了……
所以转而使用循环来解决,超时的算法我就放在最后面了。
暴力搜索的循环写法可以类比图的bfs遍历搜索,使用一个队列来遍历整个图。每遍历到一个节点就把节点入队,遍历完队首所有邻接节点后队首出队。
题解
#include <cstdio>
#include <string.h>
#include <queue>
#include <limits.h>
using namespace std;
int l, r, c,mmin;
char map[50][50][50];
int vis[50][50][50];
typedef struct op
{
int x;
int y;
int z;
int step;
} point;
int judge(int x, int y ,int z)
{
if (x < 0 || y < 0 || z < 0 || x >= l || y >= r || z >= c)
return 0;
if (map[x][y][z] == '#' || vis[x][y][z] == 1)
return 0;
return 1;
}
// 通过遍历矩阵来模拟移动,代码量很小
const int arrx[6] = {0, 0, 0, 0, 1, -1};
const int arry[6] = {0, 0, 1, -1, 0, 0};
const int arrz[6] = {1, -1, 0, 0, 0, 0};
void bfs(int x, int y, int z)
{
queue<point> q;
point buf;
buf.x = x;
buf.y = y;
buf.z = z;
buf.step = 0;
q.push(buf);
vis[x][y][z] = 1;
while (!q.empty())
{
point cur = q.front();
if (map[cur.x][cur.y][cur.z] == 'E')
{
if (cur.step < mmin)
{
mmin = cur.step;
}
}
q.pop();
//模拟移动,好好看好好学
for (int i = 0; i < 6; i++)
{
int newx = cur.x + arrx[i];
int newy = cur.y + arry[i];
int newz = cur.z + arrz[i];
if (judge(newx, newy, newz))
{
buf.x = newx;
buf.y = newy;
buf.z = newz;
buf.step = cur.step + 1;
vis[newx][newy][newz] = 1;
q.push(buf);
}
}
}
return;
}
int main()
{
while (scanf("%d %d %d", &l, &r, &c) && l != 0)
{
mmin = INT_MAX;
point start;
getchar();
memset(vis, 0, sizeof(vis));
for (int i = 0; i < l; i++)
{
if (i > 0)
getchar();
for (int j = 0; j < r; j++)
{
for (int k = 0; k < c; k++)
{
scanf("%c", &map[i][j][k]);
if (map[i][j][k] == 'S')
{
start.x = i;
start.y = j;
start.z = k;
}
if (k == c - 1)
{
getchar();
}
}
}
}
// printf("********************\n");
// for (int i = 0; i < l; i++)
// {
// for (int j = 0; j < r; j++)
// {
// for (int k = 0; k < c; k++)
// {
// printf("%c ", map[i][j][k]);
// if (k == c - 1)
// {
// printf("\n");
// }
// }
// }
// }
bfs(start.x, start.y, start.z);
if (mmin == INT_MAX)
{
printf("Trapped!\n");
}
else
{
printf("Escaped in %d minute(s).\n", mmin);
}
}
return 0;
}
超时题解(个人觉得没问题)
#include <cstdio>
#include <string.h>
#include <limits.h>
int count;
int l, r, c;
char map[50][50][50];
int
vis[50][50][50];
typedef struct op
{
int x;
int y;
int z;
} point;
int max;
void dfs(int x, int y, int z)
{
if (map[x][y][z] == 'E')
{
// printf("i'm out!!\n");
if (count < max && count != 0)
max = count;
return;
}
if (x - 1 >= 0)
{
if (map[x - 1][y][z] != '#' && vis[x - 1][y][z] == 0)
{
count++;
vis[x][y][z] = 1;
dfs(x - 1, y, z);
vis[x][y][z] = 0;
count--;
}
}
if (y - 1 >= 0)
{
if (map[x][y - 1][z] != '#' && vis[x][y - 1][z] == 0)
{
count++;
vis[x][y][z] = 1;
dfs(x, y - 1, z);
vis[x][y][z] = 0;
count--;
}
}
if (z - 1 >= 0)
{
if (map[x][y][z - 1] != '#' && vis[x][y][z - 1] == 0)
{
count++;
vis[x][y][z] = 1;
dfs(x, y, z - 1);
vis[x][y][z] = 0;
count--;
}
}
if (x + 1 < l)
{
if (map[x + 1][y][z] != '#' && vis[x + 1][y][z] == 0)
{
count++;
vis[x][y][z] = 1;
dfs(x + 1, y, z);
vis[x][y][z] = 0;
count--;
}
}
if (y + 1 < r)
{
char buf1 = map[x][y + 1][z];
int buf2 = vis[x][y + 1][z];
if (map[x][y + 1][z] != '#' && vis[x][y + 1][z] == 0)
{
count++;
vis[x][y][z] = 1;
dfs(x, y + 1, z);
vis[x][y][z] = 0;
count--;
}
}
if (z + 1 < c)
{
if (map[x][y][z + 1] != '#' && vis[x][y][z + 1] == 0)
{
count++;
vis[x][y][z] = 1;
dfs(x, y, z + 1);
vis[x][y][z] = 0;
count--;
}
}
return;
}
int main()
{
while (scanf("%d %d %d", &l, &r, &c) && l != 0)
{
max = INT_MAX;
point start;
getchar();
memset(vis, 0, sizeof(vis));
for (int i = 0; i < l; i++)
{
if (i > 0)
getchar();
for (int j = 0; j < r; j++)
{
for (int k = 0; k < c; k++)
{
scanf("%c", &map[i][j][k]);
if (map[i][j][k] == 'S')
{
start.x = i;
start.y = j;
start.z = k;
}
if (k == c - 1)
{
getchar();
}
}
}
}
//这是用来检查输入是否正确的
// printf("********************\n");
// for (int i = 0; i < l; i++)
// {
// for (int j = 0; j < r; j++)
// {
// for (int k = 0; k < c; k++)
// {
// printf("%c ", map[i][j][k]);
// if (k == c - 1)
// {
// printf("\n");
// }
// }
// }
// }
count = 0;
dfs(start.x, start.y, start.z);
if (max == INT_MAX)
{
printf("Trapped!\n");
}
else
{
printf("Escaped in %d minute(s).\n", max);
}
}
return 0;
}