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,该分裂分裂,该继续走继续走,所产生的一下层的点,进入q,s++ // 返回值: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; } }