C++知识点总结(41):广度优先搜索

广度优先搜索

  • 一、广度优先搜索
    • 1. 意义
    • 2. 分析
    • 3. 基本程序
  • 二、例题
  • 三、DFS VS. BFS

*注:如果还没有学过 结构体 或者 栈/队列/优先队列 的同学请仔细看完我的总结哦~

一、广度优先搜索

1. 意义

广度优先搜索(Breadth-first search,简称BFS),别名宽度优先搜索,是一种搜索算法。但是相较于深度优先搜索(Depth-first search,简称DFS),对于某些题目,时间复杂度更低。举个例子,对于走迷宫哪条路径最短,BFS 找来很多人一起走,只要出现有人走到终点的情况,那么这条路径必定是最短的,而 DFS 不能。

2. 分析

假如有这样一个迷宫:

12345
1*
2**
3
4***
5*
步数位置存活
0(1,1)1
1(2,1)1
2(3,1)2
3(4,1)/(3,2)1 / 1
4(3,3)/(5,1)2 / 1
5(2,3)(3,4)/(5,2)

3. 基本程序

首先我们要理解为什么要用队列,这是因为在每次人没有存活的时候就要删除一开始的元素,那么用队列会更方便。

结构体队列的定义方法:

#include <queue>
struct Node
{int x;bool flag;char c;
}; // 记得写分号
queue <Node> q;
q.push({1, 0, 'c'}); // 入队
auto [a, b, c] = q.front(); // 获取队首元素
cout << a << " " << b << " " << c; // 输出: 1 0 'c'

伪代码如下:

void bfs()
{vis[1][1] = 1; // 起点标记q.push({1, 1, 0}); // 起点入队while (!q.empty) // 非空时{// 获取队首元素并出队// 判断是否为终点// 是:结束// 遍历四个方向// 获得新的x,y坐标,存为tx,ty// 判断能否走(边界,障碍,访问)// 能走:tx,ty,step+1入队}
}

二、例题

1. 最短路径模板

#include <iostream>
#include <queue>
using namespace std;struct Node
{int x, y; // 当前坐标int step; // 当前步数
};int n;
int a[105][105];
int sx, sy, ex, ey;
queue <Node> q; // 结构体队列
bool vis[105][105];
int dx[5] = {-1, 0, 0, 1};
int dy[5] = {0, -1, 1, 0};void bfs()
{vis[sx][sy] = 1; // 起点标记q.push({sx, sy, 0}); // 起点入队while (!q.empty()) // 非空时{// 获取队首元素并出队auto [fx, fy, fstep] = q.front();q.pop();// 判断是否为终点if (fx==ex && fy==ey){cout << fstep;return;}// 遍历四个方向for (int i = 0; i <= 3; i++){int tx = fx+dx[i];int ty = fy+dy[i];if (a[tx][ty]==0 && tx>=1 && tx<=n && ty>=1 && ty<=n && vis[tx][ty]==0){vis[tx][ty] = 1;q.push({tx, ty, fstep+1});}}}
}int main()
{// 输入cin >> n;for (int i = 1; i <= n; i++)for (int j = 1; j <= n; j++)cin >> a[i][j];cin >> sx >> sy >> ex >> ey;// bfsbfs();return 0;
}

2. 跳跃的马

2.1 审题

根据国际象棋规则,马只能走日字格。现在给定你一个 n × m n\times m n×m 的矩阵,已知小马在矩阵的 (x, y),请你给出一个步数矩阵,计算每个格子到达的步数(不能到达就填充 -1)。文件:horse.cpp要求行末尾没有空格

输入:

3 3 1 1

输出:

0 3 2
3 -1 1
2 1 4

2.2 思路

明确日子格的偏移量!

x x x 偏移量 y y y 偏移量
-2-1
-1-2
1-2
2-1
-21
-12
12
21

2.3 参考答案

#include <iostream>
#include <cstdio>
#include <queue>
#include <cstring>
using namespace std;struct Node
{int x, y;int step;
};int n, m;
int x, y;
int a[105][105];
int dx[10] = {-2, -1, 1, 2, -2, -1, 1, 2};
int dy[10] = {-1, -2, -2, -1, 1, 2, 2, 1};
queue <Node> q;void bfs()
{a[x][y] = 0; // 起点标记q.push({x, y, 0}); // 起点入队while (!q.empty()) // 非空时{// 获取队首元素并出队auto [fx, fy, fstep] = q.front();q.pop();// 遍历八个方向for (int i = 0; i <= 7; i++){int tx = fx+dx[i];int ty = fy+dy[i];if (tx>=1 && tx<=n && ty>=1 && ty<=m && a[tx][ty]==-1){a[tx][ty] = fstep+1;q.push({tx, ty, fstep+1});}}}
}int main()
{freopen("horse.in", "r", stdin);freopen("horse.out", "w", stdout);// 输入cin >> n >> m >> x >> y;memset(a, -1, sizeof(a));// bfsbfs();// 输出for (int i = 1; i <= n; i++){for (int j = 1; j <= m; j++){cout << a[i][j] << " \n"[j==m];}}fclose(stdin);fclose(stdout);return 0;
}

3. 今天就上 200 200 200

3.1 审题

题目描述

《今天就上 200 200 200 层》是一款考验玩家策略的益智类游戏,游戏中需要操控 yls 上到摩天大楼的第 200 200 200 层,摩天大楼的每一层都有一个光圈,光圈上会显示一个数字 k i k_i ki,光圈有 2 2 2 个箭头,一个向上,一个向下,上下的层数等于光圈上的数字,但注意,并不是所有的光圈都是有效的,例如 3 3 3 3 3 3 1 1 1 2 2 2 5 5 5 代表 k i k_i ki k 1 = 3 k_1 = 3 k1=3 k 2 = 3 k_2 = 3 k2=3…),如果 yls 当前在 1 1 1 层,选择"上"的箭头可以到达 4 4 4 层,选择"下"的箭头是不起作用的,因为没有 − 2 -2 2 层。
假设 yls 在 x x x 层,想要到 y y y 层,至少需要选择几次光圈?

输入描述

输入共 2 2 2 行。
第一行为三个用空格隔开的正整数,表示 n n n(表示摩天大楼的层数) , x , y ,x,y ,x,y 1 ≤ n ≤ 200 1 \le n \le 200 1n200 1 ≤ x , y ≤ n 1 \le x, y \le n 1x,yn)。
第二行为 n n n 个用空格隔开的非负整数,表示 k i k_i ki 1 ≤ k i ≤ n 1 \le k_i \le n 1kin)。

输出描述

一行,即最少按键次数,若无法到达,则输出 − 1 -1 1

样例1

输入

5 1 5
3 3 1 2 5

输出

3

3.2 参考答案

#include <iostream>
#include <queue>
using namespace std;struct Node
{int f;int step;
};int n;
int s, e;
int k[205];
bool vis[205];
queue <Node> q;void bfs()
{vis[s] = 1; // 起点标记q.push({s, 0}); // 起点入队while (!q.empty()){// 获取队首元素并出队auto [ff, fstep] = q.front();q.pop();// 判断是否为终点if (ff == e){cout << fstep;return;}// 往上走int up = ff+k[ff];if (up<=n && vis[up]==0){vis[up] = 1;q.push({up, fstep+1});}// 往下走int down = ff-k[ff];if (down>=1 && vis[down]==0){vis[down] = 1;q.push({down, fstep+1});}}cout << -1;return;
}int main()
{// 输入cin >> n >> s >> e;for (int i = 1; i <= n; i++)cin >> k[i];// bfsbfs();return 0;
}

三、DFS VS. BFS

BFS 适用于求源点和目标结点距离近的情况,例如求最少步数;
DFS 适用于求解一个任意符合方案中的一种或者遍历所有情况,例如能否到达、求所有路径数、全排列。

对于不同的题目,二者的优势也各不相同,在今天的三道例题中都推荐用时间复杂度更低的 BFS。

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

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

相关文章

【代码随想录】【算法训练营】【第65天】 [卡码94]城市间货物运输I

前言 思路及算法思维&#xff0c;指路 代码随想录。 题目来自 卡码网。 day 65&#xff0c;周四&#xff0c;继续ding~ [卡码94] 城市间货物运输I 题目描述 卡码94 城市间货物运输I 解题思路 前提&#xff1a; 思路&#xff1a; 重点&#xff1a; 代码实现 C语言 Be…

ubuntu文件夹加密

veracrypt 安装 wget https://launchpad.net/veracrypt/trunk/1.24-update7/+download/veracrypt-1.24-Update7-setup.tar.bz2tar -jxvf veracrypt-1.24-Update7-setup.tar.bz2 uname -m sudo ./veracrypt-1.24-Update7-setup-console-x64 # 选1 # 一直回车 选yes安装成功创…

快递查询|阿里云实现调用API接口

整体请求流程 介绍&#xff1a; 本次解析通过阿里云云市场的云服务来实现程序中对快递包裹实时监控&#xff0c;首先需要准备选择一家可以提供快递查询的商品。 https://market.aliyun.com/apimarket/detail/cmapi00065859#skuyuncode5985900001 步骤1: 选择商品 如图点击…

网站外链还有没有作用

前言 还记得“内容为王&#xff0c;外链为皇”这句话吗&#xff1f;在以前网站外链是网站优化中非常主要的环节。那时候做一个网站&#xff0c;只要不停的发外链&#xff0c;收录就不会差&#xff0c;于是大部分站长都使劲发外链。 有市场就有商场&#xff0c;大家都看到外链…

【国内超大型智能算力中心建设白皮书 2024】_智算中心算力规划

文末有福利&#xff01; 智算中心建设通过领先的体系架构设计&#xff0c;以算力基建化为主体、以算法基建化为引领、以服务智件化为依托&#xff0c;以设施绿色化为支撑&#xff0c;从基建、硬件、软件、算法、服务等全环节开展关键技术落地与应用。 一、体系架构 &#xf…

基于扩散的生物打印策略,控制可打印性和结构特性

基于扩散的生物打印策略&#xff0c;控制可打印性和结构特性 在生物打印中&#xff0c;将生物材料和细胞按特定设计逐层堆积&#xff0c;构建具有复杂结构和功能的三维组织结构。微挤出生物打印是最常用的方法&#xff0c;其核心是生物墨水&#xff0c;它由聚合物材料和细胞组…

国漫推荐02

童年经典 1.《雷速登闪电冲线》赛车、竞赛 2.《雷速登之翼飞冲天》直升机、竞赛 3.《纳米神兵》该剧进述11岁少年小光如何用自己的善良和热忱感化原本企图侵略地球的外星族群&#xff0c;并带领他们一同对抗其他邪恶的外星人&#xff0c;由此一步步成长为拯救地球和人类的英雄…

在线绘图小工具

在线绘图小工具 文章说明程序源码功能展示源码下载 文章说明 本文主要是在看了袁老师的canvas绘图小视频后所写&#xff0c;记录一个简单的canvas绘图功能&#xff0c;并学习一下较为传统的JavaScript事件写法&#xff0c;同时了解一下拖拽事件的更合理写法&#xff0c;等待后续…

C++相关概念和易错语法(18)(array、模板)

1.array &#xff08;1&#xff09;普通数组的劣势 当我们直接越界修改值时&#xff0c;一般会在编译时就被拦截 但是越界访问&#xff0c;只要访问距离不算特别大&#xff0c;那么也可以越界访问 当我们不直接越界修改或访问&#xff0c;间接去访问和修改能越界非常远 这里的…

翻牌器单独设置前后缀样式

翻牌器单独设置前后缀样式 <template><div :style"[fontStyle,styleBackGroundColor]"><!-- <span style"color: #1d1d1d"> {{optionData}}</span>--><!-- 设置前缀样式 --><span class"prefix" …

【面试题】MySQL(第四篇)

1.详细说一下一条 MySQL 语句执行的步骤 Server 层按顺序执行 SQL 的步骤为&#xff1a; 客户端请求 -> 连接器&#xff08;验证用户身份&#xff0c;给予权限&#xff09; 查询缓存&#xff08;存在缓存则直接返回&#xff0c;不存在则执行后续操作&#xff09; 分析器&a…

怎么样的主食冻干算好冻干?品质卓越、安全可靠的主食冻干分享

当前主食冻干市场产品质量参差不齐。一些品牌过于追求营养数据的堆砌和利润的增长&#xff0c;却忽视了猫咪健康饮食的基本原则&#xff0c;导致市场上出现了以肉粉冒充鲜肉、修改产品日期等不诚信行为。更令人担忧的是&#xff0c;部分产品未经过严格的第三方质量检测便上市销…

高效的采购管理系统,提升企业采购效能利器

在当今全球化和竞争激烈的商业环境中&#xff0c;企业如何有效管理和优化采购过程&#xff0c;直接影响到企业的运营成本和市场竞争力。传统的手工或半自动化采购管理方式已经难以满足现代企业的需求&#xff0c;因此&#xff0c;越来越多的企业开始转向高效的采购管理系统&…

深度优先算法-DFS(算法篇)

算法之深度优先算法 深度优先算法(DFS) 概念&#xff1a; 深度优先算法(DFS)跟BFS算法一样是用于遍历图的算法&#xff0c;但是DFS并不像BFS算法一样&#xff0c;它搜索出来的路径不具有最短性&#xff0c;并且dfs算法类似于枚举&#xff0c;因此DFS算法一般用于求出问题的所…

雅思词汇及发音积累 2024.7.11

计算机房 computer lab 计算机房 mainframe 主机 monitor 屏幕 screen 键盘 keyboard 键盘 mouse 鼠标 memory 内存 loudspeaker 扬声器 printer 打印机 scanner 扫描仪 photocopier/copier 复印机 laser printer 激光打印机 software programme 程序 viruses /ˈvaɪərəsɪz…

linux ssh 远程执行shell 获取返回值

#!/bin/bashSCRIPTcd / && lsresult$(ssh -o StrictHostKeyCheckingno root10.204.0.1 $SCRIPT) echo "result: $result"或者下面# 远程服务器的IP地址或主机名 HOSTremote_host # 远程服务器的用户名 USERusername # 远程执行的脚本 SCRIPT/path/to/remote/…

Hadoop的HA模式搭建

准备三台虚拟机 bigdata007&#xff0c;bigdata008&#xff0c;bigdata009 1.前置工作 1.修改虚拟机的IP地址和hostname 2.配置集群中的ip映射&#xff08;/etc/hosts&#xff09; 192.168.111.57 bigdata007 192.168.111.58 bigdata008 192.168.111.59 bigdata0093.关闭虚拟…

武夷山细节决定成败抓质量求生存

在当今竞争激烈的市场环境中&#xff0c;细节决定成败&#xff0c;质量求生存的理念已成为企业发展的关键。蓝鹏测控科技有限公司&#xff0c;一家专业从事工业测量领域的高新技术企业&#xff0c;正是秉持这一理念&#xff0c;在工业测径仪领域取得了显著成就。 蓝鹏测控科技…

pandas修改时间索引报错处理

import pandas as pd import numpy as np import osdfpd.DataFrame(index[a,b,c],data{序列:[1,2,3]}) df.rename(index{a:a1},inplaceTrue) print(df) print(df.index.dtype)df1pd.DataFrame(index[2024-01-01,2024-01-02,2024-01-03],data{序列:[1,2,3]}) df1.rename(index{2…

Excel——REPLACE函数实现敏感信息打码

第一步&#xff1a; 以素材Excel文档为例。 在F2单元格中输入函数“REPLACE(B2,4,5,"*****")”&#xff0c;输入完毕后&#xff0c;按Enter键开始计算&#xff0c;并使用填充柄对其他区域进行填充。 这个函数的意思是&#xff1a;从第4位数字开始的5个数字用5个“…