蓝桥杯 算法提高 学霸的迷宫 java

Adv147 算法提高 学霸的迷宫

题目如下:
image-20200817103823681

这道题是经典的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;
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值