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

给定一个 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
(2)走到的点为0,不为1。
g[x][y]=0;
(3)走到的位置还没被走过
d[x][y]=-1;
if(x>=0&&x=0&&y

更新满足条件点的距离,即将上一个点走过的距离加上 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开始)

手动模拟

AcWing 844. 走迷宫 (每日一题)_第1张图片

注:BFS类似于一颗二叉树

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

AcWing 844. 走迷宫 (每日一题)_第2张图片

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

上下左右

AcWing 844. 走迷宫 (每日一题)_第3张图片

代码

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
				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)

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

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

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

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

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

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

你可能感兴趣的:(每日一题,蓝桥杯上岸,算法,数据结构,java,leetcode,蓝桥杯,每日一题,BFS)