You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

88 lines
2.3 KiB

2 years ago
package class48;
public class Problem_0499_TheMazeIII {
// 节点:来到了哪?(r,c)这个位置
// 从哪个方向来的d -> 0 1 2 3 4
// 之前做了什么决定让你来到这个位置。
public static class Node {
public int r;
public int c;
public int d;
public String p;
public Node(int row, int col, int dir, String path) {
r = row;
c = col;
d = dir;
p = path;
}
}
public static String findShortestWay(int[][] maze, int[] ball, int[] hole) {
int n = maze.length;
int m = maze[0].length;
Node[] q1 = new Node[n * m], q2 = new Node[n * m];
int s1 = 0, s2 = 0;
boolean[][][] visited = new boolean[maze.length][maze[0].length][4];
s1 = spread(maze, n, m, new Node(ball[0], ball[1], 4, ""), visited, q1, s1);
while (s1 != 0) {
for (int i = 0; i < s1; i++) {
Node cur = q1[i];
if (hole[0] == cur.r && hole[1] == cur.c) {
return cur.p;
}
s2 = spread(maze, n, m, cur, visited, q2, s2);
}
Node[] tmp = q1;
q1 = q2;
q2 = tmp;
s1 = s2;
s2 = 0;
}
return "impossible";
}
public static int[][] to = { { 1, 0 }, { 0, -1 }, { 0, 1 }, { -1, 0 }, { 0, 0 } };
public static String[] re = { "d", "l", "r", "u" };
// maze迷宫走的格子
// n 行数
// m 列数
// 当前来到的节点cur -> (r,c) 方向 路径(决定)
// v [行][列][方向] 一个格子其实在宽度有限遍历时是4个点
// q 下一层的队列
// s 下一层队列填到了哪size
// 当前点cur该分裂分裂该继续走继续走所产生的一下层的点进入qs++
// 返回值q增长到了哪返回size -> s
public static int spread(int[][] maze, int n, int m,
Node cur, boolean[][][] v, Node[] q, int s) {
int d = cur.d;
int r = cur.r + to[d][0];
int c = cur.c + to[d][1];
// 分裂去!
if (d == 4 || r < 0 || r == n || c < 0 || c == m || maze[r][c] != 0) {
for (int i = 0; i < 4; i++) {
if (i != d) {
r = cur.r + to[i][0];
c = cur.c + to[i][1];
if (r >= 0 && r < n && c >= 0 && c < m && maze[r][c] == 0 && !v[r][c][i]) {
v[r][c][i] = true;
Node next = new Node(r, c, i, cur.p + re[i]);
q[s++] = next;
}
}
}
} else { // 不分裂!继续走!
if (!v[r][c][d]) {
v[r][c][d] = true;
q[s++] = new Node(r, c, d, cur.p);
}
}
return s;
}
}