首页 > 其他分享 >【BFS】(代码详解)

【BFS】(代码详解)

时间:2024-03-22 18:59:23浏览次数:27  
标签:int 代码 位置 偏移量 BFS 队列 详解 dx dy

全面学习BFS的可以参照以下路径,本文章只附上部分代码的解释作为学习记录共勉(星星眼)
原文链接:https://blog.csdn.net/m0_62881629/article/details/125072287

给定一个 n×mn×m 的二维整数数组,用来表示一个迷宫,数组中只包含 00 或 11,其中 00 表示可以走的路,11 表示不可通过的墙壁。
最初,有一个人位于左上角 (1,1)(1,1) 处,已知该人每次可以向上、下、左、右任意一个方向移动一个位置。
请问,该人从左上角移动至右下角 (n,m)(n,m) 处,至少需要移动多少次。

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

输入格式
第一行包含两个整数 nn 和 mm。
接下来 nn 行,每行包含 mm 个整数(00 或 11),表示完整的二维数组迷宫。

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

数据范围
1≤n,m≤1001≤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

#include <iostream>
#include <algorithm>
#include <queue>
#include <cstring>
using namespace std;

typedef pair<int, int>PII;
const int N = 110;

int n, m;
int  g[N][N]; //存储地图
int  d[N][N]; // 储存每一个点到起点的距离
PII  q[N * N]; //手动定义一个队列

int bfs() {
	int h = 0, t = 0; // 队头和队尾
	q[0] = {0, 0}; // 将起点坐标放入队列的第一个位置
	memset(d, -1, sizeof(d)); 
    // 将所有的d数组元素初始化为-1,表示未访问过
	d[0][0] = 0; // 起点到起点的距离为0

	int dx[4] = {-1, 0, 1, 0}, dy[4] = {0, 1, 0, -1}; 
/*当 i = 0 时,表示向上移动,对应的偏移量为 (dx[0], dy[0]) = (-1, 0),即在行上减1,列上不变;
当 i = 1 时,表示向右移动,对应的偏移量为 (dx[1], dy[1]) = (0, 1),即在行上不变,列上加1;
当 i = 2 时,表示向下移动,对应的偏移量为 (dx[2], dy[2]) = (1, 0),即在行上加1,列上不变;
当 i = 3 时,表示向左移动,对应的偏移量为 (dx[3], dy[3]) = (0, -1),即在行上不变,列上减1。*/

while (h <= t) { // 队列不为空时执行循环
   	auto t = q[h++]; 
    for (int i = 0; i < 4; i++) { // 遍历四个方向
		*int x = t.first + dx[i], y = t.second + dy[i]; 
  // t.first 表示当前位置的 x 坐标,t.second 表示当前位置的 y 坐标
  //dx[i] 表示在第 i 个方向上 x 坐标的偏移量,dy[i] 表示在第 i 个方向上 y 坐标的偏移量

// 判断下一个位置是否在边界内、在地图内、没有走过
if (x >= 0 && x < n && y >= 0 && y < m && g[x][y] == 0 && d[x][y] == -1) {
// g[x][y] == 0 判断位置 (x, y) 是否可通行,其中 g 可能是一个二维数组或向量,d[x][y] == -1 判断位置 (x, y) 是否未被访问过
		d[x][y] = d[t.first][t.second] + 1; 
    	// 更新到达下一个位置的步数
		q[++tt] = {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;

  1. 初始化起点坐标 (0, 0),将其加入队列 q 中,并初始化距离数组 d 为未访问状态,起点到起点的距离为 0。
  2. 定义四个方向的偏移量数组 dxdy,分别表示上、右、下、左四个方向的移动情况。
  3. 在队列不为空时,不断从队列中取出坐标 (x, y) 进行处理,然后遍历四个方向,判断是否可以向上、右、下、左四个方向移动,即判断下一个位置是否在边界内、在地图内、可通行且未被访问过。
  4. 如果满足条件,则更新到达下一个位置的步数,并将下一个位置加入队列。
  5. 重复以上步骤,直到遍历完所有可达的位置或找到终点 (n-1, m-1)
  6. 最终返回终点到起点的最短距离

标签:int,代码,位置,偏移量,BFS,队列,详解,dx,dy
From: https://blog.csdn.net/2301_76518242/article/details/136811175

相关文章

  • 如何回退已经合并的master代码?
    如何回退已经合并的master代码?在CodeUp(一个代码托管平台,类似于GitLab、GitHub等)上撤销已经合并到master分支的提交,你需要遵循以下基本步骤:回滚master分支:如果你想要撤销整个合并操作并恢复到合并前的状态,你可以执行一个反向合并(revertmerge)。在Git中,这通常通过创建一个新......
  • 又一款代码神器,效率直接翻倍!免费的还是香啊!
    前言提到商汤科技,你可能仍然将其与“AI四小龙”、“计算机视觉领军企业”等标签联系在一起。然而,在ChatGPT与Sora赢得广泛关注后,商汤科技依托其深厚的人工智能技术基础,迅速开发出自己的大型模型及人工智能应用产品,其中就包括即将向你介绍的“小浣熊”智能助手。手机和电脑都适用......
  • 分享基于PDF.js的pdf阅读器代码
    一、前言有时候开发PC端web页面的时候会遇到PDF预览、下载等功能,为了兼容浏览器,需要找一款前端插件进行开发。比较好的PDF插件,就是mozilla的pdf.js(注意是mozilla,如果你百度遇到需要收费的,那应该是下载错了)。而从mozilla的Github仓库去找想要的代码,如果你不熟悉,想直接使用的......
  • 【教程】深入探究 JS代码混淆与加密技术
     ......
  • Java版本spring cloud + spring boot企业电子招投标系统源代码
    招投标管理系统是一个集门户管理、立项管理、采购项目管理、采购公告管理、考核管理、报表管理、评审管理、企业管理、采购管理和系统管理于一体的综合性应用平台。它适用于招标代理、政府采购、企业采购和工程交易等业务的企业,旨在提高项目管理的效率和质量。该系统以项目为主......
  • 1.基于搜索的路径规划:BFS、DFS、Dijkstra、A*、JPS
    1.概览可以对比不同算法的小动画 PathFinding.js(qiao.github.io)工作空间规划机器人有不同的形状和大小碰撞检测需要了解机器人的几何形状,耗时且难度大 我们希望将机器人表示为点,只需要把工作空间转换为配置空间C-obstacle,将原始的空间膨胀,这是一次性的C-space......
  • 操作系统综合题之“请填写信号量值并说明操作结果(正常、阻塞或唤醒。如阻塞或者唤醒,需
    1.问题:题36表是两个同步进程的模拟执行,生产者将物品放入共享缓冲区供消费者使用,缓冲区可放2件物品,使用2个信号量,并置初值为S1=2,S2=0.现已知操作情况,请填写信号量值并说明操作结果(正常、阻塞或唤醒。如阻塞或者唤醒,需说明阻塞或者被唤醒的是P1还是P2)。(提示:缓冲区满,不许放物品;缓......
  • Java知识学习13(AQS详解)(转载)
    1、AQS介绍?AQS的全称为AbstractQueuedSynchronizer,翻译过来的意思就是抽象队列同步器。这个类在java.util.concurrent.locks包下面。AQS就是一个抽象类,主要用来构建锁和同步器。publicabstractclassAbstractQueuedSynchronizerextendsAbstractOwnableSynchronizer......
  • Redis系列十:Pipeline详解
    转载自:https://blog.csdn.net/w1lgy/article/details/84455579一、pipeline出现的背景:redis客户端执行一条命令分4个过程:发送命令-〉命令排队-〉命令执行-〉返回结果 1这个过程称为Roundtriptime(简称RTT,往返时间),mgetmset有效节约了RTT,但大部分命令(如hgetall,并没......
  • 【Linux】基础 IO(动静态库)-- 详解
    一、前言为什么要使用别人的代码?主要是为了提高程序开发的效率和程序的健壮性。当别人把功能都实现了,然后我们再基于别人的代码去做二次开发,那么效率当然就提高了。其次,这里基于的别人当然不是随便找的一个人,而特指的是顶尖的工程师,也就是说如果我们的代码出了问题,一般不会......