其实本质和二维的图形并无太大差异
题目描述
题目链接
简单描述:
你被困在一个3D地牢中且继续寻找最短路径逃生!地牢由立方体单位构成,立方体单位中有的会充满岩石。向上下前后左右移动一个单位需要一分钟。你不能向对角线的四个方向移动且迷宫四周环绕着许多岩石。
是否可以逃出地牢?如果可以,则需要多少时间?
Input - 输入:
输入的第一行包含一个数,表示地牢的数量。
每个地牢的描述,其第一行包含三个数L,R和C(均小于等于30)。
L表示地牢的层数;R和C分别表示每层地牢的行与列的大小。随后输入地牢的层数L,每层中包含R行,每行中包含C个字符。每个字符表示地牢的一个单元。‘#‘表示岩石单元,’.‘表示空白单元。你的起始位置在点’S’,出口为’E’。每层地牢的输入后都有一个空行。当L,R和C均为0时,输入结束。
Output - 输出 每个迷宫对应一行输出。
如果可以逃生,则输出如下:Escaped in x minute(s).
x为最短脱离时间。
如果无法逃生,则输出如下:Trapped!
题目分析
- 层数、行数、列数:我们要涉及到三维数组
对于三维数组:我们只需要在二维数组上加一层循环即可。第一层循环为z轴(层数),第二层循环为x轴(行数), 第三层循环为y轴(列数) - 求最短时间(即最短路径)用bfs
上下前后左右:我们用的三个大小为6数组来表示对应坐标的变化。
代码
#include <iostream>
#include <algorithm>
#include <cstdio>
#include <queue>
#include <cstring>
using namespace std;
const int N = 33;
char q[N][N][N];
int book[N][N][N];
int l, r, d, ans;
int zz[] = {1, -1, 0, 0, 0, 0}, xx[] = {0, 0, -1, 0, 1, 0}, yy[] = {0, 0, 0, 1, 0, -1};
struct f{
int z;
int x;
int y;
int s;
};
queue <f> qu;
int bfs(int sz, int sx, int sy){
struct f a;
a.z = sz;
a.x = sx;
a.y = sy;
a.s = 0;
qu.push(a);
book[sz][sx][sy] = 1;
while(!qu.empty()){
struct f b = qu.front();
qu.pop();
int k = 0;
for(int i = 0; i < 6; i ++){
struct f c;
c.x = b.x + xx[i];
c.z = b.z + zz[i];
c.y = b.y + yy[i];
c.s = b.s + 1;
if(c.x < 0 || c.y < 0 || c.z < 0 || c.z >= l || c.x >= r || c.y >= d) continue;
if(book[c.z][c.x][c.y] == 0 && q[c.z][c.x][c.y] != '#'){
qu.push(c);
book[c.z][c.x][c.y] = 1;
if(q[c.z][c.x][c.y] == 'E'){
// ans = c.s;
return c.s;
}
}
}
}
return -1;
}
int main(void){
int sz, sx, sy;
while(1){
scanf("%d %d %d", &l, &r, &d);
if(l == 0 && r == 0 && d == 0) return 0;
for(int i = 0; i < l; i ++){
for(int j = 0; j < r; j ++){
for(int k = 0; k < d; k ++){
cin >> q[i][j][k];
if(q[i][j][k] == 'S'){
sz = i;
sx = j;
sy = k;
}
}
}
}
// ans = 0;
ans = bfs(sz, sx, sy);
if(ans >= 0) printf("Escaped in %d minute(s).\n", ans);
else puts("Trapped!");
while(qu.size()) qu.pop();
memset(book, 0, sizeof(book));
}
}
几个细节:
- 多组输入,记得memset标记数组。
- 因为涉及到三维,判断是否为合法坐标时,一定要按照顺序走,三个参数,不重不漏(粗心大意,找了半个多小时才看出来)