Adv147 算法提高 学霸的迷宫
题目如下:
这道题是经典的bfs,对这个不太理解的建议学习下,挺简单的
其他的都是跟模板差不多的,求路径的时候我是把到这个格子的方向存了起来,最后再从出口那个格子往前迭代拼接起完整的路径,具体的可以看代码,都是有注释的。
当然我这方法还是麻烦了,完全可以从刚开始就存路径,存方向最后还要自己拼一下,建议你们可以这样做。
package adv;
import java.util.ArrayList;
import java.util.List;
import java.util.Scanner;
/**
* @Description: 算法提高 学霸的迷宫
* @ClassName: Adv147
* @author: fan.yang
* @date: 2020/08/14 16:51
*/
public class Adv147 {
//存迷宫的数组
private static char[][] map;
//记录是否访问过
private static int[][] visit;
//字典序D > L > R > U 这样写就是为了字典序最小
private static int[][] dir = {{1 , 0},{0 , -1},{0 , 1},{-1 , 0}};
//4个方向的字符
private static char[] dirCh = {'D', 'L', 'R', 'U'};
//考虑到还要输出路径 这题直接用list算了
private static List<Node> list = new ArrayList<>();
//设置个头指针
private static int front = -1;
private static int n,m;
public static void bfs(int beginX, int beginY, int endX, int endY){
//将起点存进去 front存进去的还是-1 起点的话前面是没东西的
Node node = new Node(beginX, beginY, front++, ' ');
list.add(node);
//这里我直接设置死循环,找到出口才能结束
while(true){
//循环4次代表4个方向 每个方向都走一下
for(int i = 0;i < 4;i++){
int newX = list.get(front).getX() + dir[i][0];
int newY = list.get(front).getY() + dir[i][1];
//如果要走的下一个格子是无效的 直接跳过
//无效分几种情况 1.越界 2.已经走过 3.不可通过
if(newX < 0 || newY < 0 || newX > n - 1 || newY > m - 1 || map[newX][newY] == '1'
|| visit[newX][newY] == 1){
continue;
}
//能到这里就是有效的情况
//记录下走过这个格子了
visit[newX][newY] = 1;
node = new Node(newX, newY, front, dirCh[i]);
//存到list里
list.add(node);
//如果这个格子就是出口 直接结束
if(newX == endX && newY == endY){
return;
}
}
front++;
}
}
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
n = scanner.nextInt();
m = scanner.nextInt();
map = new char[n][m];
for(int i = 0;i < n;i++){
//因为每个格子没有间隔 所以就按String输入
map[i] = scanner.next().toCharArray();
}
visit = new int[n][m];
//开始就是左上角 这里就搞个(0,0) 出口就是(n - 1 , m - 1)
bfs(0, 0, n - 1, m - 1);
StringBuffer sb = new StringBuffer();
//因为我走每个格子的时候 顺便存了下走的方向 所以直接迭代一下
int index = list.size() - 1;
while(true){
//用头指针从出口往前迭代
Node node = list.get(index);
index = node.getPre();
//当头指针为-1时 就是回到入口了 结束
if(index == -1){
break;
}
sb.append(node.getDir());
}
System.out.println(sb.length());
//因为我是到这迭代的 所以再倒一下才是从入口到出口的
System.out.println(sb.reverse());
}
}
class Node{
private int x;
private int y;
private int pre;
private char dir;
public Node(int x, int y, int pre, char dir) {
this.x = x;
this.y = y;
this.pre = pre;
this.dir = dir;
}
public int getX() {
return x;
}
public void setX(int x) {
this.x = x;
}
public int getY() {
return y;
}
public void setY(int y) {
this.y = y;
}
public int getPre() {
return pre;
}
public void setPre(int pre) {
this.pre = pre;
}
public char getDir() {
return dir;
}
public void setDir(char dir) {
this.dir = dir;
}
}