蓝桥杯算法心得——迷宫(bfs+映射+HashMap)

大家好,我是晴天学长,bfs经典题目迷宫,也蓝桥杯真题之一,运用到了传统的bfs加上映射技巧,并用HashMap储蓄了传送门,需要的小伙伴请自取哦!💪💪💪


1 )迷宫

在这里插入图片描述


2) .算法思路

1.建立一个map去储蓄传送门,并用链表数组表示
2.标记数组
3.偏移量技巧

1.接收数据
并把传送门储蓄到map中
2.建立一个Queue双向链表
3.首元素入队
4.是否为空
5.要统计层数,所以要size
6.首元素出队,先看是否有传送门,并压入队尾,记得标记数组的作用
7.上下左右,符合条件的压入队尾
8.层数++

add方法
1.二维坐标映射法


3).代码示例

package LanQiaoTest.BFS;

import java.util.*;

public class 迷宫 {
    static int N = 2010;
    static Map<Integer, List<int[]>> map = new HashMap<>();
    static boolean[][] st = new boolean[N][N];

    //偏移量技巧
    static int[] dx = {0, 0, -1, 1};
    static int[] dy = {1, -1, 0, 0};
    static int n, m;

    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        n = sc.nextInt();
        m = sc.nextInt();
        for (int i = 0; i < m; i++) {
            int x1 = sc.nextInt() - 1;
            int y1 = sc.nextInt() - 1;
            int x2 = sc.nextInt() - 1;
            int y2 = sc.nextInt() - 1;
            add(x1, y1, x2, y2);
            add(x2, y2, x1, y1);
        }
        Queue<int[]> queue = new LinkedList<>();
        queue.offer(new int[]{n - 1, n - 1});
        st[n - 1][n - 1] = true;
        //累计答案
        int ans = 0;
        //计算层数
        int x = 0;
        while (!queue.isEmpty()) {
            //判断要开枝散叶的元素有几个
            int size = queue.size();
            while (size-- > 0) {
                //用数组元素去接收
                int[] curr = queue.poll();
                int a = curr[0], b = curr[1];
                //累加答案
                ans += x;
                //我先看你有没有传送门
                if (map.containsKey(a * n + b)) {
                    List<int[]> list = map.get(a * n + b);
                    for (int[] g : list) {
                        if (!st[g[0]][g[1]]) {
                            queue.offer(g);
                            st[g[0]][g[1]] = true;
                        }
                    }
                }
                for (int i = 0; i < 4; i++) {
                    int newX = a + dx[i];
                    int newY = b + dy[i];
                    if (newX >= 0 && newX < n && newY >= 0 && newY < n && !st[newX][newY]) {
                        queue.offer(new int[]{newX, newY});
                        st[newX][newY] = true;
                    }
                }
            }
            //层数++;
            x++;
        }
        System.out.printf("%.2f", ans * 1.0 / (n * n));
    }

    static void add(int x1, int y1, int x2, int y2) {
        if (!map.containsKey(x1 * n + y1)) map.put(x1 * n + y1, new ArrayList<>());
        map.get(x1 * n + y1).add(new int[]{x2, y2});
    }
}


4).总结

  • 快速建立一个数组元素
    new int[]{x2,y2}
  • Map 接口中有两个常用的方法:put(key, value) 和 get(key)。

put(key, value) 方法用于向 Map 中添加元素,其中参数 key 为该元素的键,参数 value 为该元素的值。如果该键之前不存在于 Map 中,该方法将会添加新元素;如果该键之前已经存在于 Map 中,该方法将会更新该键对应的值。

get(key) 方法用于获取 Map 中与指定键相关联的值。如果该键不存在于 Map 中,该方法将会返回 null。

  • 利用存储结构获取元素(不需要new)
    int[] curr = queue.poll();
    List<int[]> list = map.get(a * n + b);
    int a = curr[0], b = curr[1];

a.static Map<Integer, List<int[]>> map = new HashMap<>();
b.List list = new ArrayList<>();
c.if (!map.containsKey(x1 * n + y1)) map.put(x1 * n + y1, new ArrayList<>());

  • Map可以存链表,链表也可以存数组为单位的元素。
  • 二维数组的映射技巧,可以把一个二维的两个坐标变成一个唯一的值。(二维坐标有规律的情况下),公式x*m+y。

原题链接:

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

晴天学长

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值