当前位置: 首页 > news >正文

蓝桥杯——走迷宫(BFS)

这是一个经典的BFS算法
在这里插入图片描述

1. BFS算法保证最短路径

  • 核心机制:广度优先搜索按层遍历所有可能的路径,首次到达终点的路径长度即为最短步数。这是BFS的核心优势。
  • 队列的作用:通过队列按先进先出的顺序处理节点,确保每一步探索的都是当前层所有可能的节点,不会跳过更短的路径。

2. 坐标与地图的映射

  • 地图存储:使用二维数组 map 存储迷宫,其中每个元素的值表示该位置是否可通行(如 0 为可通行,1 为障碍物)。
  • 坐标处理:你的代码假设输入的起点和终点坐标是 1-based(即从1开始),但在数组中直接以 0-based 索引访问,未做转换。这可能导致越界或定位错误(需修正)。

3. 步数记录与状态管理

  • 步数数组 dp:记录从起点到每个坐标的最小步数。初始化时起点步数为 0(但你的代码中未显式初始化,可能导致逻辑错误)。
  • 访问标记:通过 dp[nextx][nexty] == 0 判断节点是否被访问过,避免重复计算。

4. 移动规则与边界检查

  • 四个方向移动:通过 dxdy 数组定义右、下、左、上四个方向的坐标变化。
  • 边界条件:检查坐标是否在 [0, n)[0, m) 范围内,防止数组越界。
  • 障碍物判断:你的代码中允许移动到 map[nextx][nexty] != 0 的区域,但通常逻辑应为 map[nextx][nexty] == 0 表示可通行(此处存在逻辑错误)。

5. 终止条件

  • 终点判断:当前节点坐标等于终点坐标时,直接输出步数并返回。
  • 无解处理:队列清空后仍未到达终点,输出 -1 表示无解。

代码如下

import java.util.*;
import java.util.concurrent.LinkedBlockingDeque;
// 1:无需package
// 2: 类名必须Main, 不可修改

public class Main {
     public static class node {
        int x;
        int y;

        public node(int x, int y) {
            this.x = x;
            this.y = y;
        }
    }

    public static void main(String[] args) {
        // 创造点对象,方便数据操作

        // 创建一个数组用来记录地图,地图为nxm,
        

        // 创建一个数组记录该位置累计的最小的步数

        // 创建一个需要拓展点的队列
        // 这个队列是很有必要的,若是这个队列里面有值,就代表可以拓展,就可以避免走不出去的情况

        // 开始向四个方向的路走,要判断这个方向的路是否可走(边界、障碍物)、
        // 如果可走就将该点存入队列,确保队列还有值,还能继续在迷宫里走

        // 终止条件,是否到达终点,到终点就将值传进去

        //基础传值操作
        Scanner scan = new Scanner(System.in);
        int n = scan.nextInt();
        int m = scan.nextInt();
        int[][] map = new int[n][m];
        for (int i = 0; i < n; i++) {
            for (int j = 0; j < m; j++) {
                map[i][j] = scan.nextInt();
            }
        }
        int startx = scan.nextInt();
        int starty = scan.nextInt();
        int endx = scan.nextInt();
        int endy = scan.nextInt();

        //这里有一个混淆点,题目给我们的坐标(1,1) (5,5)但对应在数组上的索引应该是[0,0] [4,4]

        node start = new node(startx-1, starty-1);
        node end = new node(endx-1, endy-1);

        //只需要一张地图和起点,终点
        BFS(map, start, end);
        scan.close();
    }


    public static void BFS(int[][] map, node start, node end) {
        //数据初始化
        int n = map.length;
        int m = map[0].length;

        int[] dx = {0, 1, 0, -1};
        int[] dy = {1, 0, -1, 0};

        int[][] dp = new int[n][m];
//        Arrays.stream(dp).forEach(ints -> Arrays.fill(ints, -1));

//        if (map[start.x][start.y] == 1) {
//            System.out.println(-1);
//            return;
//        }

        //初始化队列将起点放进去0
        Queue<node> queue = new LinkedBlockingDeque<>();
        queue.add(start);


        //只要队列不为空就可以一直走
        while (!queue.isEmpty()) {
            node now = queue.poll();//从队列里面取值,取完值就得将该值删除

            //当前节点等于终点直接输出结果
            if (now.x == end.x && now.y == end.y) {
                System.out.println(dp[now.x][now.y]);
                return;
            }

            int nowx = now.x;
            int nowy = now.y;

            for (int i = 0; i < 4; i++) {
                int nextx = nowx + dx[i];
                int nexty = nowy + dy[i];
                node next = new node(nextx, nexty);
                //边界判断 x[0,n) y[0,m) ,还有地图不能等于1,并且这个地方没被走过
                if (
                        (nextx >= 0 && nextx < n) &&
                                (nexty >= 0 && nexty < m) &&
                                (map[nextx][nexty] != 0) &&
                                (dp[nextx][nexty] == 0)
                ) {
                    queue.add(next);//下一步可走就将该点加入队列,假如若有四次可走就将这四个点都加入队列,
                    //之后就可以从这队列里面取可走的点然后继续拓展可走的点的四个方向

                    dp[nextx][nexty] = dp[nowx][nowy] + 1;//走过的地方步数都大于1
                }

            }
        }
        //无法到达终点
        System.out.println(-1);
    }

}

这里有一个混淆点,由于他题目给的坐标和索引不对应导致卡了半天没想到居然还能过71.4%在这里插入图片描述在这里插入图片描述

相关文章:

  • QT QML布局
  • LabVIEW 中串口设备与采集卡的同步精度
  • [Python] 企业内部应用接入钉钉登录,端内免登录+浏览器授权登录
  • Uncaught ReferenceError: process is not defined
  • Linux学习笔记——文件系统基础与根文件系统详解
  • 记一次Sqlserver数据库性能分析
  • 剑指Offer(数据结构与算法面试题精讲)C++版——day8
  • 一文详解OpenCV环境搭建:Ubuntu20.4使用CLion配置OpenCV开发环境
  • SQL 函数概述
  • Vue3实战四、项目布局及布局功能实现
  • 晋城市电子健康证上传照片尺寸要求及手机拍照制作方法
  • PyCharm使用Flask启动项目后,如何修改文件,开启启动加载或是热启动,不用重启项目,直接生效。
  • 双引擎驱动:解密音视频体验的QoS技术底座与QoE感官革命
  • ElasticSearch迁移数据
  • “剪贴板劫持“攻击:黑客利用虚假验证码通过入侵网站窃取数据
  • 自动化框架及其设计搭建浅谈(三)--自动化测试框架设计最佳实践
  • Elasticearch数据流向
  • Qt添加资源文件
  • APP应用为什么要选择使用游戏盾?从攻防本质到技术突围
  • 6.2 利用yaml进行参数的保存
  • 南通昨晚最新疫情爆发/重庆网站seo费用
  • 年终总结汇报ppt模板/西安企业seo外包服务公司
  • 做网站得做多少网页/seo咨询服务
  • 厦门网站建设培训/竞价排名服务
  • 淘宝网站推广策略/东莞seo计费
  • 大型门户网站模板/怎么自己制作网页