迷宫最短路径【Java实现】

news2024/11/26 21:22:28

题目描述

现有一个n∗m大小的迷宫,其中1表示不可通过的墙壁,0表示平地。每次移动只能向上下左右移动一格,且只能移动到平地上。假设左上角坐标是(1,1),行数增加的方向为x增长的方向,列数增加的方向为y增长的方向,求从迷宫左上角到右下角的最少步数的路径。

输入描述

第一行两个整数n、m(2≤n≤100,2≤m≤100),分别表示迷宫的行数和列数;

接下来n行,每行m个整数(值为01),表示迷宫。

输出描述

从左上角的坐标开始,输出若干行(每行两个整数,表示一个坐标),直到右下角的坐标。

数据保证最少步数的路径存在且唯一。

样例

输入

3 3
0 1 0
0 0 0
0 1 0

输出

1 1
2 1
2 2
2 3
3 3

解释

假设左上角坐标是(1,1),行数增加的方向为x增长的方向,列数增加的方向为y增长的方向。

可以得到从左上角到右下角的最少步数的路径为:(1,1)=>(2,1)=>(2,2)=>(2,3)=>(3,3)

思路分析

  • 关于迷宫中最短路径的问题一般都采用广度优先搜索的思想,因为广度搜索“横扫千军”的形式确保了当前点到达其身边点时的距离一定是最小,以此类推,这样搜索下去到达目标点的距离也一定是最小的。
  • 不过本题的难点是在于要求我们输出最短距离的具体路径,如果是深度优先搜索的话,使用递归就可以很好的输出路径,但是广度优先并不由递归的方式实现,因此如何确保到达目标位置后如何还能找到“回头路”(即怎么知道从那个点出发过来的)是我们要解决的问题。
  • 一个好的办法是创建一个和地图同样维度的二维数组Pair prePosition[n][m],其中Pair是我们的自定义类,其存放点的坐标信息,而在prePosition数组中则是存放到达当前点的上一个点的坐标信息,如prePosition[i][j]=new Pair(x,y)代表广度优先搜索中(x,y)的下一个点是(i,j),初始(0,0)的上一个坐标是(-1,-1)
  • 我们通过普通的广度优先搜索从起点走向终点,在这一过程中注意记录当前点的上一个坐标,来到最后一个点时,只需要通过简单的递归就可以根据之前留下的“线索”定位到起始位置,接着进行打印即可。

代码实现

package homework;

import java.util.LinkedList;
import java.util.Scanner;

public class Main {

	public static void main(String[] args) {
		Scanner scanner = new Scanner(System.in);
		int n = scanner.nextInt();
		int m = scanner.nextInt();
		int arr[][] = new int[n][m];
		for (int i = 0; i < n; i++) {
			for (int j = 0; j < m; j++) {
				arr[i][j] = scanner.nextInt();
			}
		}
		BFS(arr, n, m);
	}

	public static void BFS(int arr[][], int n, int m) {
		LinkedList<Pair> queue = new LinkedList<Pair>();
		// 广度遍历时,(x,y)下标对应的上一个坐标
		Pair prePosition[][] = new Pair[n][m];
		Pair pair = new Pair(0, 0);
		prePosition[0][0] = new Pair(-1, -1);
		queue.addLast(pair);
		while (!queue.isEmpty()) {
			int size = queue.size();
			for (int i = 0; i < size; i++) {
				Pair poll = queue.poll();
				arr[poll.row][poll.cols] = 1;
				if (poll.row == n - 1 && poll.cols == m - 1) {
					printCoord(prePosition, n - 1, m - 1);
					return;
				} else {
					Pair pre = new Pair(poll.row, poll.cols);
					if (poll.row - 1 >= 0 && arr[poll.row - 1][poll.cols] == 0) {
						queue.addLast(new Pair(poll.row - 1, poll.cols));
						prePosition[poll.row - 1][poll.cols] = pre;
					}
					if (poll.row + 1 < n && arr[poll.row + 1][poll.cols] == 0) {
						queue.addLast(new Pair(poll.row + 1, poll.cols));
						prePosition[poll.row + 1][poll.cols] = pre;
					}
					if (poll.cols + 1 < m && arr[poll.row][poll.cols + 1] == 0) {
						queue.addLast(new Pair(poll.row, poll.cols + 1));
						prePosition[poll.row][poll.cols + 1] = pre;
					}
					if (poll.cols - 1 >= 0 && arr[poll.row][poll.cols - 1] == 0) {
						queue.addLast(new Pair(poll.row, poll.cols - 1));
						prePosition[poll.row][poll.cols - 1] = pre;
					}
				}
			}
		}

	}

	static void printCoord(Pair prePosition[][], int row, int cols) {
		if (row != -1 && cols != -1) {
			Pair pair = prePosition[row][cols];
			printCoord(prePosition, pair.row, pair.cols);
			System.out.println((row + 1) + " " + (cols + 1));
		}
	}

}

class Pair {
	int row;
	int cols;

	public Pair(int x, int y) {
		this.row = x;
		this.cols = y;
	}

}
image-20230210135137794

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/336213.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Protocol Buffers V3语法全解

目录protobuf介绍protobuf使用protoc命令语法定义消息类型指定字段类型分配字段编号指定字段规则添加更多消息类型注释保留字段从.proto文件生成了什么&#xff1f;值类型默认值枚举使用其他消息类型导入定义嵌套类型更新消息类型未知字段any任意类型oneofoneof 特性兼容性问题…

awk命令

一.介绍 awk是专门为文本处理设计的编程语言&#xff0c;是一门数据驱动的编程语言。与sed类似&#xff0c;都是以数据驱动的行处理软件&#xff0c;主要用于数据扫描&#xff0c;过滤和汇总。数据可以来自于标准输入&#xff0c;管道或者文件。 二.语法 awk是一种处理文本文件…

Vite+Vue3实现版本更新检查,实现页面自动刷新

ViteVue3实现版本更新检查&#xff0c;实现页面自动刷新1、使用Vite插件打包自动生成版本信息2、Vite.config.ts配置3、配置环境变量4、路由配置现有一个需求就是实现管理系统的版本发版&#xff0c;网页实现自动刷新页面获取最新版本 搜索了一下&#xff0c;轮询的方案有点浪费…

Mysql:避免重复的插入数据方法汇总

最常见的方式就是为字段设置主键或唯一索引&#xff0c;当插入重复数据时&#xff0c;抛出错误&#xff0c;程序终止&#xff0c;但这会给后续处理带来麻烦&#xff0c;因此需要对插入语句做特殊处理&#xff0c;尽量避开或忽略异常&#xff0c;下面我介绍4种方法&#xff1a; …

【Windows10】电脑副屏无法调节屏幕亮度?解决方法

先说下情况&#xff0c;本人对显示器不太懂&#xff0c;属于小白 这个副屏无法调节的问题出现也已经很久了&#xff0c;但是之前亮度适合就无所谓&#xff0c;今天突然按了之后很亮&#xff0c;于是就找问题。 第一步&#xff0c;我直接百度&#xff0c;遇事不决&#xff0c;百…

59 双向循环神经网络【动手学深度学习v2】

59 双向循环神经网络【动手学深度学习v2】 深度学习学习笔记 学习视频&#xff1a;https://www.bilibili.com/video/BV12X4y1c71W/?spm_id_fromautoNext&vd_source75dce036dc8244310435eaf03de4e330 核心思想&#xff1a;取决于过去和未来的上下文&#xff0c;来预测当前的…

Apache Spark 命令注入(CVE-2022-33891)

利用范围 Spark Core - Apache <3.0.3 3.1.1 < Spark Core - Apache <3.1.2 3.2.0 < Spark Core - Apache <3.2.1 环境搭建 修改bin目录下的spark-shell 修改如下&#xff0c;添加调试端口 变动如上 然后启动 ./spark-shell --conf spark.acls.enabletrue即…

使用百度地图官方WEB API,提示 “ APP 服务被禁用“ 问题的解决方法

问题描述 项目上用了百度地图官方WEB API&#xff0c;打开界面时百度地图无法打开&#xff0c;出现弹窗&#xff1a; APP被您禁用啦。详情查看&#xff1a;http://lbsyun.baidu.com/apiconsole/key#。 原因分析&#xff1a; 查看错误信息&#xff1a;"status":240,…

Word文档带有权限密码怎么办?

Word文档的权限密码指的是什么&#xff1f;其实这是Word文档的保护方法之一&#xff0c;具体指Word文档的编辑、修改受到了限制&#xff0c;需要输入密码才能进行。 设置了权限密码的Word文档还是可以直接打开&#xff0c;只有当需要编辑或者修改内容的时候&#xff0c;才会发…

CSDN版的详细MarkDown的使用教程

MarkDown的使用欢迎使用Markdown编辑器新的改变功能快捷键合理的创建标题&#xff0c;有助于目录的生成如何改变文本的样式插入链接与图片如何插入一段漂亮的代码片生成一个适合你的列表创建一个表格设定内容居中、居左、居右SmartyPants创建一个自定义列表如何创建一个注脚注释…

雅思经验(7)

我发现雅思阅读要命的不是难度&#xff0c;而是时间的把控。考试时间是总共一小时&#xff0c;但是要写三篇文章&#xff0c;之后总共40道题目&#xff0c;也就是说每篇文章平均是13.3道。但是他们很多人说&#xff0c;如果誊写答案需要花掉3、4分钟每篇&#xff0c;也就是说真…

学习IB课程的宝藏网站,有需求选择

很多学习IB课程的同学都会觉得IB课程很难&#xff0c;平时作业很多根本没时间找资料&#xff0c;其实不用担心&#xff0c;关于IB课程学习的网站&#xff0c;小编已经帮大家整理好了&#xff0c;建议收藏起来&#xff01; 数学类IB网站&#xff1a;Revision Villag 数学对于会的…

Bard AI:训练过程中使用了多少数据?

近年来&#xff0c;人工智能取得了长足的进步&#xff0c;并在科技界掀起了波澜。 随着谷歌最近推出新的人工智能聊天机器人 Bard&#xff0c;人们对这项技术的工作原理以及训练它的内容感到好奇。 人工智能技术的关键组成部分之一是训练过程中使用的数据量&#xff0c;这有助于…

聊聊数据仓库是什么

随着数据通过各种方式创造了巨大价值&#xff0c;各领域的企业开始不断挖掘数据的作用&#xff0c;数据的重要性得到了社会各界的共同认可。像我们熟知的数据治理、数据管理、数据标准以及数据资产都是因为数据地位不断提升&#xff0c;企业开始重视起数据全生命周期流程&#…

整数规划、对偶理论、线性规划经典例题讲解

整数规划是一类要求问题的解中的全部或一部分变量为整数的数学规划&#xff0c;应用范围极其广泛。不仅在工业和工程设计和科学研究方面有许多应用&#xff0c;而且在计算机设计、系统可靠性和经济分析等方面也有新的应用。通过前面的学习&#xff0c;我们已经掌握了整数规划的…

Java测试——selenium具体操作

selenium的前置准备工作可以参考我之前的博客&#xff1a;Java测试——selenium的安装与使用教程 这篇博客讲解一下selenium的常见操作 先创建driver ChromeDriver driver new ChromeDriver();输入网址 driver.get("https://www.baidu.com");常见操作 查找元素…

[数据分析] 数据指标体系搭建

在数据分析的学习过程中&#xff0c;我们通常会要求掌握以下两点: 1.理解数据&#xff0c;懂得从数据中发现业务指标(学会如何去看懂数据) 2.使用相关指标去分析数据&#xff0c;同时使用多个指标去分析一个问题(了解常见的指标) 当我们拿到数据(通常以Excel或者数据库方式去…

机器学习评估指标的十个常见面试问题

评估指标是用于评估机器学习模型性能的定量指标。它们提供了一种系统和客观的方法来比较不同的模型并衡量它们在解决特定问题方面的成功程度。通过比较不同模型的结果并评估其性能可以对使用哪些模型、如何改进现有模型以及如何优化给定任务的性能做出正确的决定&#xff0c;所…

java世界String的那些事

String的创建机理&#xff1a; 由于String在Java世界中使用过于频繁&#xff0c;Java为了避免在一个系统中产生大量的String对象&#xff0c;引入了字符串常量池。其运行机制是&#xff1a;创建一个字符串时&#xff0c;首先检查池中是否有值相同的字符串对象&#xff0c;如果…

【Nacos】Nacos配置中心客户端配置更新源码分析

上文我们说了服务启动的时候从远程Nacos服务端拉取配置&#xff0c;这节我们来说下Nacos服务端配置的变动怎么实时通知到客户端&#xff0c;首先需要注册监听器。 注册监听器 NacosContextRefresher类会监听应用启动发布的ApplicationReadyEvent事件&#xff0c;然后进行配置…