题后总结思路
- 走迷宫无权重问题,要求求最短路径,实际上就是考差宽搜;
- 熟练掌握STL容器的使用很重要,例如Queue,Abstract.SimpleEntry;
- 为了方便理解,本题采用新建类Node替代Queue中泛型Abstract.SimpleEntry
题目描述
众所周知,Teutonic Knight是某RTS游戏中,移动速度最快的角色。而且他热衷于参加赛跑比赛。现在他想知道他最快需要用多长时间才可以到达终点,假设他没有开加速挂。 起初,他站在第1张图的某个位置(用‘S’标识),终点在第k张图的某个位置(用‘E’标识),在除最后一张图外,每一张图上有且仅有一个传送点(用‘T’标识),可以将他传送到下一张图的某个位置,用‘t’标识。传送不需要任何时间,可以理解为瞬间完成。每次移动一个单位距离耗时1秒。 现在Teutonic Knight想知道他在全程狂奔的情况下,最快需要多长时间才能到达终点。
输入
第一行三个数k,n,m(k,n,m<=100)。 接下来k个图,两个图之间用一个空行隔开,每个图有n行,每行m个字符,字符含义如下:
‘#’ – 该位置为墙或者障碍。
‘.’ – 该位置可以正常行走。
‘T’ – 该位置有一传送点。
‘t’ – 从上图传送来的位置。
‘S’ – Teutonic Knight的起始位置。‘S’仅有一个。
‘E’ – 出口。‘E’仅有一个。
输出
仅一行,输出到达终点的最少时间。 如不能离开,输出“Trapped Maze!!!”。
样例输入
3 5 6
##.S#.
##.###
##…
.##.#.
##…#T
##.t…
##.##.
##.#…
T.#…#
#…##
###t##
##…#E
#…##.
#.##…
#…#
输出
33
代码展示:
import java.util.*;
//存放坐标类
class Node {
int x;
int y;
public Node(int x, int y) {
this.x = x;
this.y = y;
}
}
public class Main {
static int n, a, b;
static final int N = 10000;
static char[][] GetChar = new char[N][N];
static int[][] time = new int[N][N];
//定义偏移量
static int[] dx = {0, 1, 0, -1};
static int[] dy = {1, 0, -1, 0};
//Node型队列 方便读取某个节点的横纵坐标
static Queue<Node> queue = new ArrayDeque<>();
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
// 分别读入 n 个图 a 行 b 列
n = sc.nextInt();
a = sc.nextInt();
b = sc.nextInt();
//按行读取字符串 一共 n*a行 b列
for (int k = 0; k < n * a; k++) {
GetChar[k] = sc.next().toCharArray();
}
//定义未访问过的字符串
for (int i = 0; i < n * a; i++) {
for (int j = 0; j < b; j++) {
time[i][j] = 0;
}
}
//找到起点 S 开始遍历 S点在第一张图
f:
for (int i = 0; i < n * a; i++) {
for (int j = 0; j < b; j++) {
if (GetChar[i][j] == 'S') {
bfs(i, j);
break f;
}
}
}
}
public static void bfs(int x, int y) {
queue.add(new Node(x, y));
time[x][y] = 0;
GetChar[x][y] = '#';
while (!queue.isEmpty()) {
Node head = queue.remove();
int sx, sy;
for (int i = 0; i < 4; i++) {
sx = dx[i] + head.x;
sy = dy[i] + head.y;
//只要它在范围内 并且不是墙和没走过的前提下 判定它的情况
if (sx >= 0 && sx < n * a && sy >= 0 && sy < b && GetChar[sx][sy] != '#') {
//1.若是 '.' --> 继续走
if (GetChar[sx][sy] == '.') {
time[sx][sy] = time[head.x][head.y] + 1;
GetChar[sx][sy] = '#';
queue.add(new Node(sx, sy));
}
//2.若是 ’T‘ -->传送到下个点继续走
if (GetChar[sx][sy] == 'T') {
GetChar[sx][sy] = '#';
queue.clear();
ff:
for (int j = sx; j < n * a; j++) {
for (int k = 0; k < b; k++) {
//找到一个立即停止当前循环
if (GetChar[j][k] == 't') {
time[j][k] = time[head.x][head.y] + 1;
GetChar[j][k] = '#';
queue.add(new Node(j, k));
break ff;
}
}
}
}
//3.走到终点停止
if (GetChar[sx][sy] == 'E') {
time[sx][sy] = time[head.x][head.y] + 1;
System.out.println(time[sx][sy]);
return;
}
}
}
if (queue.isEmpty()) {
System.out.println("Trapped Maze!!!");
return;
}
}
}
}
运行结果(芒课网)