AcWing 844. 走迷宫 (每日一题)

文章介绍了使用广度优先搜索(BFS)解决迷宫问题,确定从左上角到右下角的最少步数,涉及数据结构和算法应用。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

给定一个 n×m 的二维整数数组,用来表示一个迷宫,数组中只包含 0 或 1,其中 0 表示可以走的路,1表示不可通过的墙壁。

最初,有一个人位于左上角 (1,1)处,已知该人每次可以向上、下、左、右任意一个方向移动一个位置。

请问,该人从左上角移动至右下角 (n,m)处,至少需要移动多少次。

数据保证 (1,1)处和 (n,m) 处的数字为 0,且一定至少存在一条通路。
输入格式
第一行包含两个整数 n和 m。
接下来 n行,每行包含 m 个整数(0 或 1),表示完整的二维数组迷宫。
输出格式

输出一个整数,表示从左上角移动至右下角的最少移动次数。
数据范围

1≤n,m≤100

输入样例:

5 5
0 1 0 0 0
0 1 0 1 0
0 0 0 0 0
0 1 1 1 0
0 0 0 1 0

输出样例:

8

分析

BFS用于求解最短路问题,且各边权重全为1(相等),一层一层往外搜。
运用BFS+队列,从起点走到终点,先到终点的即为最短距离
BFS:搜索(满足条件)
队列:将满足条件的点入队,通过出队、入队的操作,一层一层往外扩展。
如:第一层搜到的为距离1,第二层为距离2,以此类推。

走迷宫:
同时满足以下条件:
(1)x,y大于等于0并且x<n,y<m不越界
(2)走到的点为0,不为1。
g[x][y]=0;
(3)走到的位置还没被走过
d[x][y]=-1;
if(x>=0&&x<n&&y>=0&&y<m&&g[x][y]==0&&d[x][y]==-1)

更新满足条件点的距离,即将上一个点走过的距离加上 1。先到终点的为最小值
d[x][y]=d[t.first][t.second]+1;

再将满足条件的点入队, 用于继续判断。
q[++tt]=new PII(x,y);
注:这里需要运用到PII类
作用1:获取x(行数)y(列数),用于上下左右移动+判断
作用2:将该点入队
q[++tt]= new PII(x,y);

最后直接返回距离即可
return d[n-1][m-1];(注意数组下标从0开始)

手动模拟

在这里插入图片描述

注:BFS类似于一颗二叉树

保证每一层往外扩,距离逐渐增加(入队出队)

在这里插入图片描述

注:到达交叉口的位置,将可走的点入队,再依次出队。
出队的每个点拿出来判断,如果下一个点可走,则将下一个点进入到队列尾中。
这样入队出队的操作保证了一层一层往外扩,并且搜索到的每一层的距离相等。
如搜索到第一层,为距离为1的点,第二层,为距离为2的点,依此类推。

上下左右

在这里插入图片描述

代码

import java.io.*;
public class Main{
	
	static int N=110,hh,tt,n,m;
	//N数据为100,多开10个单位,防止越界。
	static int [][]g=new int[N][N];
	static int [][]d=new int[N][N];
	
	static PII []q=new PII[N*N];
	//最多移动整个数组,即N行N列
	public static int bfs() {
		hh=0;//初始化队头
		tt=-1;//初始化队尾
		d[0][0]=0;//第0行第0列为入口
		q[++tt]=new PII(0,0);//往队尾添加第一个点
		
		int dx[]= {-1,0,1,0};
		int dy[]= {0,1,0,-1};
		/*
		向上移动:
		dx[0]=-1 dy[0]=0 (-1,0) 列不变,行数往上移
		
		向右移动:
		dx[1]=0  dy[1]=1 (0,1)  行不变,列数往右移 
		
		向下移动:
		dx[2]=1 dy[2]=0  (1,0)  列不变,行数往下移
		
		向左移动:
		dx[3]=0 dy[3]=-1 (0,-1) 行不变,列数往左移
		*/
		while(hh<=tt) {
		    
			PII t=q[hh++];//取出队头
			
			for(int i=0;i<4;i++) {
			    //向上、下、左、右移动
				int x = t.first+dx[i];
				int y = t.second+dy[i];
				/*同时满足以下条件:
				(1)x,y大于等于0并且x<n,y<m不越界
				(2)走到的点为0,不为1,
				(3)走到的位置还没被走过
				*/
				if(x>=0&&x<n&&y>=0&&y<m&&g[x][y]==0&&d[x][y]==-1) {
					
					d[x][y]=d[t.first][t.second]+1;//满足条件,则在原来走过的距离上加一,记录走过的距离。
					
					q[++tt]=new PII(x,y);//再将该点(x,y)插入到队尾,用于下面的判断。
				}
			
			}
		}
				
		return d[n-1][m-1];//返回从起点到终点的距离,数组下标从0开始,即n-1,m-1
		
	}
	public static void main(String []args) throws IOException {
		BufferedReader in = new BufferedReader(new InputStreamReader(System.in));
		//BufferedWriter out = new BufferedWriter(new OutputStreamWriter(System.out));
		String []s = in.readLine().split(" ");
		n = Integer.parseInt(s[0]);
		m=Integer.parseInt(s[1]);
		for(int i=0;i<n;i++) {
			String []st = in.readLine().split(" ");
			for(int j=0;j<m;j++) {
				g[i][j]=Integer.parseInt(st[j]);//读入数据
				
				d[i][j]=-1;//初始化每行每一列的位置,代表还没走过。
			}
		}
		
		System.out.println(bfs());//输出数字
		//out.write(bfs());输出数字对应的字符
		//out.close();
	}	
}

class PII{//PII
int  first,second;
public PII(int first,int second){//构造方法
    this.first=first;
    this.second=second;
}
}

往期回顾

不清楚蓝桥杯考什么的点点下方👇

考点秘籍

想背纯享模版的伙伴们点点下方👇

蓝桥杯省一你一定不能错过的模板大全(第一期)

蓝桥杯省一你一定不能错过的模板大全(第二期)

蓝桥杯省一你一定不能错过的模板大全(第三期)

蓝桥杯省一你一定不能错过的模板大全(第四期)!!!

想背注释模版的伙伴们点点下方👇

蓝桥杯必背第一期

蓝桥杯必背第二期

往期精彩回顾

蓝桥杯上岸每日N题 第一期(一)!!!

蓝桥杯上岸每日N题第一期(二)!!!

蓝桥杯上岸每日N题第一期(三)!!!

蓝桥杯上岸每日N题第二期(一)!!!

蓝桥杯上岸每日N题第三期(一)!!!

蓝桥杯上岸每日N题 第四期(最少刷题数)!!!

蓝桥杯上岸每日N题 第五期(山)!!!

蓝桥杯上岸每日N题 第六期(求阶乘)!!!

蓝桥杯上岸每日N题 第七期(小猫爬山)!!!

蓝桥杯上岸每日N题 第八期 (全球变暖)!!!

蓝桥杯每日N题 (消灭老鼠)

蓝桥杯每日N题(杨辉三角形)

蓝桥杯每日N题 (砝码称重)

蓝桥杯上岸每日N题(鸡尾酒)

操作系统期末题库 第九期(完结)

LeetCode Hot100 刷题(第三期)

idea创建SpringBoot项目报错解决方案

数据库SQL语句(期末冲刺)

想看JavaB组填空题的伙伴们点点下方 👇

填空题

竞赛干货

算法竞赛字符串常用操作大全

蓝桥杯上岸必刷!!!(模拟/枚举专题)

蓝桥杯上岸必背!!! (第三期 DP)

蓝桥杯上岸必背!!!(第四期DFS)

蓝桥杯上岸必背!!!(第五期BFS)

蓝桥杯上岸必背!!!(第六期树与图的遍历)

蓝桥杯上岸必背!!!(第七期 最短路算法)

蓝桥杯上岸必背!!!(第八期 简单数论)

蓝桥杯上岸必刷!!!(进制、数位专题)

蓝桥杯上岸考点清单 (冲刺版)!!!

蓝桥杯上岸必背模板 (纯享版)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

寸 铁

感谢您的支持!

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

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

打赏作者

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

抵扣说明:

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

余额充值