2019年javaA组迷宫

这篇博客介绍了一种解决迷宫问题的方法,通过宽度优先搜索(BFS)和动态规划(DP)找到每个位置到终点的最短距离,并按字典序找到最短路径。代码示例展示了如何使用ArrayDeque实现队列并结合坐标类(Node)进行搜索。
摘要由CSDN通过智能技术生成

迷宫

思路:之前2017年的迷宫只需要看能否走出迷宫,所以直接用的dfs+标记完成。这次的迷宫是需要得到最短路径和最短路径中的字典序最小,所以先采用dp和bfs得到迷宫中每一个能到达的点离终点的最短距离,然后再从起点按照每个点的最短距离为下一个点的最短距离加一的顺序搜索到下一个点,且搜索时结合按照字典序进行搜索。

总结:之前的题常常使用dfs来深搜,这方面的题一般直接利用函数内再次调用函数(利用栈的思想)来进行。这道题使用的是bfs宽度优先搜索结合ArrayDeque(利用队列的思想)进行,从而不断将子节点加入,又从根节点依次层层遍历:用ArrayDeque构造一个队列,队列中的节点是自己创造的内部类(以后可以借鉴这个思想来同时放一个坐标),用ArrayDeque的offer方法将节点加入队列尾部,用poll方法删除第一个节点且返回被删除的节点(ArrayDeque也可以用作栈,push方法添加元素到栈顶,peek方法得到第一个元素,pop方法删除栈顶元素)

代码:

import java.util.ArrayDeque;
import java.util.Scanner;

public class _03平方拆分 {

	static int n = 30;
	static int m = 50;
	static int[][] map = new int[n][m];
	static int[][] dis = new int[n][m];
	static int[] dx = { 1, 0, 0, -1 };
	static int[] dy = { 0, -1, 1, 0 };

	static void countDis(int x, int y) {
		for (int i = 0; i < n; i++) {
			for (int j = 0; j < m; j++) { //之前把这里的m写成了n
				dis[i][j] = -1;
			}
		}

		ArrayDeque<Node> arrayDeque = new ArrayDeque<>();
		dis[x - 1][y - 1] = 0;// 最后一个离自己距离为0
		arrayDeque.offer(new Node(x - 1, y - 1));
		while (!arrayDeque.isEmpty()) {
			Node node = arrayDeque.poll();// 每次出来一个,后面都会加入好几个
			for (int i = 0; i < 4; i++) {
				int nx = node.x + dx[i];
				int ny = node.y + dy[i];
				if (nx >= 0 && ny >= 0 && nx < n && ny < m && dis[nx][ny] == -1 && map[nx][ny] == 0) {
					dis[nx][ny] = dis[node.x][node.y] + 1;
					arrayDeque.offer(new Node(nx, ny));
				}
			}
		}
	}

	public static void main(String[] args) {
		Scanner scanner = new Scanner(System.in);
		for (int i = 0; i < 30; i++) {
			String string = scanner.nextLine();
			for (int j = 0; j < 50; j++) {
				map[i][j] = string.charAt(j) - '0';
			}
		}

		countDis(n, m);// 填充dis数组,得到每个位置离终点的距离
		String[] strings = { "D", "L", "R", "U" }; //下面的循环中,每次都按照这个顺序搜索,就会得到字典序最小
		StringBuffer sb = new StringBuffer();
		int x = 0, y = 0;
		while (x != n - 1 || y != m - 1) { //到终点的时候不增加字符
			for (int i = 0; i < 4; i++) {
				int nx = x + dx[i];
				int ny = y + dy[i];
				if (nx >= 0 && ny >= 0 && nx < n && ny < m && dis[x][y] == dis[nx][ny] + 1) {
					sb.append(strings[i]);
					x = nx;
					y = ny;
					break;//如果找到了就不用继续for循环寻找
				}
			}
		}
		System.out.println(sb);

	}

	static class Node {
		int x;
		int y;

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

	}

}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值