大家好,我是晴天学长,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。