迷宫
思路:之前2017年的迷宫只需要看能否走出迷宫,所以直接用的dfs+标记完成。这次的迷宫是需要得到最短路径和最短路径中的字典序最小,所以先采用dp和bfs得到迷宫中每一个能到达的点离终点的最短距离,然后再从起点按照每个点的最短距离为下一个点的最短距离加一的顺序搜索到下一个点,且搜索时结合按照字典序进行搜索。
总结:之前的题常常使用dfs来深搜,这方面的题一般直接利用函数内再次调用函数(利用栈的思想)来进行。这道题使用的是bfs宽度优先搜索结合ArrayDeque(利用队列的思想)进行,从而不断将子节点加入,又从根节点依次层层遍历:用ArrayDeque构造一个队列,队列中的节点是自己创造的内部类(以后可以借鉴这个思想来同时放一个坐标),用ArrayDeque的offer方法将节点加入队列尾部,用poll方法删除第一个节点且返回被删除的节点(ArrayDeque也可以用作栈,push方法添加元素到栈顶,peek方法得到第一个元素,pop方法删除栈顶元素)
代码:
import java.util.ArrayDeque;
import java.util.Scanner;
public class _03平方拆分 {
static int n = 30;
static int m = 50;
static int[][] map = new int[n][m];
static int[][] dis = new int[n][m];
static int[] dx = { 1, 0, 0, -1 };
static int[] dy = { 0, -1, 1, 0 };
static void countDis(int x, int y) {
for (int i = 0; i < n; i++) {
for (int j = 0; j < m; j++) { //之前把这里的m写成了n
dis[i][j] = -1;
}
}
ArrayDeque<Node> arrayDeque = new ArrayDeque<>();
dis[x - 1][y - 1] = 0;// 最后一个离自己距离为0
arrayDeque.offer(new Node(x - 1, y - 1));
while (!arrayDeque.isEmpty()) {
Node node = arrayDeque.poll();// 每次出来一个,后面都会加入好几个
for (int i = 0; i < 4; i++) {
int nx = node.x + dx[i];
int ny = node.y + dy[i];
if (nx >= 0 && ny >= 0 && nx < n && ny < m && dis[nx][ny] == -1 && map[nx][ny] == 0) {
dis[nx][ny] = dis[node.x][node.y] + 1;
arrayDeque.offer(new Node(nx, ny));
}
}
}
}
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
for (int i = 0; i < 30; i++) {
String string = scanner.nextLine();
for (int j = 0; j < 50; j++) {
map[i][j] = string.charAt(j) - '0';
}
}
countDis(n, m);// 填充dis数组,得到每个位置离终点的距离
String[] strings = { "D", "L", "R", "U" }; //下面的循环中,每次都按照这个顺序搜索,就会得到字典序最小
StringBuffer sb = new StringBuffer();
int x = 0, y = 0;
while (x != n - 1 || y != m - 1) { //到终点的时候不增加字符
for (int i = 0; i < 4; i++) {
int nx = x + dx[i];
int ny = y + dy[i];
if (nx >= 0 && ny >= 0 && nx < n && ny < m && dis[x][y] == dis[nx][ny] + 1) {
sb.append(strings[i]);
x = nx;
y = ny;
break;//如果找到了就不用继续for循环寻找
}
}
}
System.out.println(sb);
}
static class Node {
int x;
int y;
public Node(int x, int y) {
super();
this.x = x;
this.y = y;
}
}
}