地牢大师
- 1.题目
- 2.基本思想
- 3.代码实现
1.题目
你现在被困在一个三维地牢中,需要找到最快脱离的出路!
地牢由若干个单位立方体组成,其中部分不含岩石障碍可以直接通过,部分包含岩石障碍无法通过。
向北,向南,向东,向西,向上或向下移动一个单元距离均需要一分钟。
你不能沿对角线移动,迷宫边界都是坚硬的岩石,你不能走出边界范围。
请问,你有可能逃脱吗?
如果可以,需要多长时间?
输入格式
输入包含多组测试数据。
每组数据第一行包含三个整数 L,R,C分别表示地牢层数,以及每一层地牢的行数和列数。
接下来是 L 个 R行 C列的字符矩阵,用来表示每一层地牢的具体状况。
每个字符用来描述一个地牢单元的具体状况。
其中, 充满岩石障碍的单元格用”#”表示,不含障碍的空单元格用”.”表示,你的起始位置用”S”表示,终点用”E”表示。
每一个字符矩阵后面都会包含一个空行。
当输入一行为”0 0 0”时,表示输入终止。
输出格式
每组数据输出一个结果,每个结果占一行。
如果能够逃脱地牢,则输出”Escaped in x minute(s).”,其中X为逃脱所需最短时间。
如果不能逃脱地牢,则输出”Trapped!”。
数据范围
1
≤
L
,
R
,
C
≤
100
1≤L,R,C≤100
1≤L,R,C≤100
输入样例:
输出样例:
Escaped in 11 minute(s).
Trapped!
2.基本思想
数据量N为100,由于是3D,那么就是n3,就是100万,时间复杂度控制在O(n)中即可通过。
从起点-终点的最小步数可以直接通过BFS宽搜来进行获取,本题主要在于一些初始化操作会比较复杂麻烦些,bfs的宽搜代码就是基本模板。
3.代码实现
import java.util.*;
import java.io.*;
class Pos {
int z, x, y;
int dis;
public Pos(int z, int x, int y, int dis) {
this.z = z;
this.x = x;
this.y = y;
this.dis = dis;
}
}
class Main {
static final BufferedReader cin = new BufferedReader(new InputStreamReader(System.in));
static final int N = 110;
//六个方向
static final int[] dz = {0, 0, 0, 0, 1, -1};
static final int[] dx = {0, 0, 1, -1, 0, 0};
static final int[] dy = {1, -1, 0, 0, 0, 0};
//每一轮读入地牢层数、行数、列数
static int L, R, C;
//构建三维地图
static char[][][] mg = new char[N][N][N];
//初始点与终点
static Pos start, end;
//深搜
static int bfs() {
//队列
Queue<Pos> queue = new LinkedList<>();
//加入起点
queue.offer(start);
while (!queue.isEmpty()) {
//出队一个点
Pos cur = queue.poll();
//此时判断是否已经遇到终点
if (cur.z == end.z && cur.x == end.x && cur.y == end.y) {
return cur.dis;
}
//遍历六个方向
for (int d = 0; d < 6; d++) {
int z = cur.z + dz[d], x = cur.x + dx[d], y = cur.y + dy[d];
//判断是否越界或者遇墙
if (z < 1 || z > L || x < 1 || x > R || y < 1 || y > C || mg[z][x][y] == '#') {
continue;
}
//当前迷宫位置'.'设置为'#',这样就无需设置一个访问数组
mg[z][x][y] = '#';
//进行入队
queue.offer(new Pos(z, x, y, cur.dis + 1));
}
}
return -1;
}
public static void main(String[] args) throws Exception{
while (true) {
//读取LRC
String[] ss = cin.readLine().split(" ");
L = Integer.parseInt(ss[0]);
R = Integer.parseInt(ss[1]);
C = Integer.parseInt(ss[2]);
//若是都读到0,那么结束
if (L == 0 && R == 0 && C == 0) break;
//地图初始化
for (int z = 1; z <= L; z++) {
for (int x = 1; x <= R; x++) {
//读取当前层的地牢
String line = cin.readLine();
for (int y = 1; y <= C; y++) {
mg[z][x][y] = line.charAt(y - 1);
//获取地图开始与结束位置
if (mg[z][x][y] == 'S') {
start = new Pos(z, x, y, 0);
}else if (mg[z][x][y] == 'E'){
end = new Pos(z, x, y, 0);
}
}
}
//读取多余一行
cin.readLine();
}
//bfs(深搜)
int dis = bfs();
if (dis != -1) {
System.out.printf("Escaped in %d minute(s).\n", dis);
}else {
System.out.printf("Trapped!\n");
}
}
}
}