走迷宫(BFS宽度优先搜索)

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

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

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

数据保证 (1,1) 处和 (n,m) 处的数字为 0,且一定至少存在一条通路。

输入格式

第一行包含两个整数 n 和 m。

接下来 n 行,每行包含 m 个整数(00 或 11),表示完整的二维数组迷宫。

输出格式

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

数据范围

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就是把这一层全部搜完才会搜下一层,因此它第一次搜到的点就是该点离起始点最近的时候,适合用来解决求最小步数,最少操作几次等最短路问题。

 找的顺序如下图所示

可以看到在图上的例子里面,我们找了八次找到了终点,也就是终点到起点的距离为8。

如何实现找出队头旁边的点:

    int dx[4]={-1,1,0,0}, dy[4]={0,0,-1,1};  //用向量表示点走四个方向后的变化,分别是上下左右while(q.size()){PII t=q.front();  //得到队头q.pop();  //删掉队头,和上面的代码加起来就是取出队头for(int i=0;i<4;i++) //队头的点依次走四个方向{int x=t.first+dx[i];int y=t.second+dy[i];//点在边界内且点可以走且点是第一次被找到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;  //每次找的是它的上下左右的点,且不会找已经走过的点,所以找到的点离起点的距离就又远了1q.push({x,y});   //把这个新找到的点放进队伍中}}}

用dx和dy数组表示上下左右四个方向移动后点坐标的变化,这里的坐标(x,y)表示的是x行y列,向上就是x-1,y不变,我们把它放进dx和dy的第一个元素里,写为-1和0 

 int dx[4]={-1,1,0,0}, dy[4]={0,0,-1,1};  //用向量表示点走四个方向后的变化,分别是上下左右

四个方向的变化如下图所示: 

示例代码: 

#include<iostream>
#include<queue>
#include<cstring>
using namespace std;typedef pair<int,int> PII; //这个主要是方便队列存放点的坐标,所以需要一对int
const int N =100; 
int n,m;
int g[N][N]; //存储地图
int d[N][N]; //存储每一个点到起点的距离int bfs()
{queue<PII> q;memset(d,-1,sizeof(d));  //初始全部设为-1,表示全没走过d[0][0]=0;  //起始点到起点的距离为0q.push({0,0}); //第一个点入队int dx[4]={-1,1,0,0}, dy[4]={0,0,-1,1};  //用向量表示点走四个方向后的变化,分别是上下左右while(q.size()){PII t=q.front();  //得到队头q.pop();  //删掉队头,和上面的代码加起来就是取出队头for(int i=0;i<4;i++) //队头的点依次走四个方向{int x=t.first+dx[i];int y=t.second+dy[i];//沿着这个方向走,点在边界内,并且这个点可以走(g[x][y]==0),这个点还没有走过(d[x][y]==-1,第一次搜到的点才是最短距离)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;  //每次找的是它的上下左右的点,且不会找已经走过的点,所以找到的点离起点的距离就又远了1q.push({x,y});   //把这个新找到的点放进队伍中}}}return d[n-1][m-1];  //输出到右下角的点(终点)的最短距离
}
int main()
{cin>>n>>m;for(int i=0;i<n;i++){for(int j=0;j<m;j++){cin>>g[i][j];}}cout<<bfs()<<endl;return 0;
}

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

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

使用【画图】软件修改图片像素、比例和大小

打开电脑画图软件&#xff0c;点击开始 windows附件 画图 在画图软件里选择需要调整的照片&#xff0c;点击文件 打开 在弹出窗口中选择照片后点击打开 照片在画图软件中打开后&#xff0c;对照片进行调整。按图中顺序进行 确定后照片会根据设定的值自动调整 保存…

劲松中西医医院HPV诊疗中心分享7个预防HPV的小技巧

同居男女是HPV感染的高危人群&#xff0c;因为HPV主要通过性传播&#xff0c;而且对健康影响很大。为了有效避免男女在同居时感染HPV&#xff0c;以下是一些建议&#xff1a; 1. 同居时正确使用安全套&#xff1a;正确使用安全套可以有效地避免同居过程中被感染HPV。同时要把控…

字母异位词分组

给你一个字符串数组&#xff0c;请你将 字母异位词 组合在一起。可以按任意顺序返回结果列表。 字母异位词 是由重新排列源单词的所有字母得到的一个新单词。 示例 1: 输入: strs [“eat”, “tea”, “tan”, “ate”, “nat”, “bat”] 输出: [[“bat”],[“nat”,“tan…

二十三、RestClient操作索引库

目录 例&#xff1a;利用JavaRestClient实现创建、删除索引库&#xff0c;判断索引库是否存在 1、编写mapping映射 2、初始化JavaRestClient &#xff08;1&#xff09;导入elasticsearch的依赖 &#xff08;2&#xff09;修改elasticsearch的版本 &#xff08;3&#xf…

阅读记录【arXiv2020】 Adaptive Personalized Federated Learning

Adaptive Personalized Federated Learning 论文地址&#xff1a; https://arxiv.org/abs/2003.13461 摘要 对联邦学习算法个性化程度的研究表明&#xff0c;只有最大化全局模型的性能才会限制局部模型的个性化能力。在本文中&#xff0c;我们提倡自适应个性化联合学习&…

鸿蒙 ark ui 轮播图实现教程

前言&#xff1a; 各位同学有段时间没有见面 因为一直很忙所以就没有去更新博客。最近有在学习这个鸿蒙的ark ui开发 因为鸿蒙不是发布了一个鸿蒙next的测试版本 明年会启动纯血鸿蒙应用 所以我就想提前给大家写一些博客文章 效果图 具体实现 我们在鸿蒙的ark ui 里面列表使…

为什么 x86 操作系统从 0x7c00 处开始

0x00&#xff1a;x86 架构 BIOS 引导加载程序中的"0x7C00"之谜 你知道 x86 操作系统中的"0x7C00"这个神奇数字吗 ? "0x7C00" 是BIOS加载MBR&#xff08;主引导记录&#xff0c;磁盘中的第一个扇区&#xff09;的内存地址。操作系统或引导加载…

【Java并发】聊聊线程池原理以及实际应用

线程其实对于操作系统来说是宝贵的资源&#xff0c;java层面的线程其实本质还是依赖于操作系统内核的线程进行处理任务&#xff0c;如果频繁的创建、使用、销毁线程&#xff0c;那么势必会非常浪费资源以及性能不高&#xff0c;所以池化技术&#xff08;数据库连接池、线程池&a…

成为AI产品经理——模型评估概述

目录 一、模型宣讲和评估的原因 二、模型宣讲 三、模型评估 1. 重要特征 ① 特征来源 ②特征意义 2.选择测试样本 3.模型性能和稳定性 一、模型宣讲和评估的原因 刘海丰老师提到他们在做一个金融AI产品未注重模型指标&#xff0c;过于注重业务指标&#xff0c;导致产生…

电力行业的智能调度:数字孪生技术

随着科技的发展&#xff0c;数字孪生技术正逐渐渗透到各个行业领域&#xff0c;其中包括电力行业。数字孪生技术为电力行业带来了前所未有的机遇&#xff0c;使得电力系统的运行更加高效、安全和可持续。本文借用山海鲸可视化软件几个电力行业数字孪生案例探讨数字孪生技术在电…

HCIP数据通信——BGP协议

引言 我之前写过一篇介绍ISIS的文章&#xff0c;我打算把BGP知识总结以后再做实验。那么现在就讲述一下BGP的一些特点和概念。 BGP特点 BGP属于EGP&#xff08;EGP也是BGP前身&#xff0c;指的是具体协议&#xff0c;被淘汰了成为了BGP&#xff09;&#xff0c;无类协议。 它…

王道p149 9.设树B是一棵采用链式结构存储的二叉树,编写一个把树 B中所有结点的左、右子树进行交换的函数。(c语言代码实现)

本题代码如下 void swap(tree* t) {if (*t){treenode* temp (*t)->lchild;(*t)->lchild (*t)->rchild;(*t)->rchild temp;swap(&(*t)->lchild);swap(&(*t)->rchild);} } 完整测试代码 #include<stdio.h> #include<stdlib.h> typed…