[蓝桥杯] 双指针、BFS和DFS与图论问题
文章目录
一、日志统计
1、1 题目描述
1、2 题解关键思路与解答
二、献给阿尔吉侬的花束
2、1 题目描述
2、2 题解关键思路与解答
三、红与黑
3、1 题目描述
3、2 题解关键思路与解答
3、2、1 dfs题解代码
3、2、2 bfs题解答案
四、交换瓶子
4、1 题目描述
4、2 题解关键思路与解答
本篇文章针对蓝桥杯比赛的考点,列出双指针、BFS和DFS与图论的相关习题以及知识点的解释。希望本篇文章会对你有所帮助。
一、日志统计
1、1 题目描述
题目来源:第九届蓝桥杯省赛C++B组,第九届蓝桥杯省赛JAVAB组
题目难度:简单
题目描述:小明维护着一个程序员论坛。现在他收集了一份”点赞”日志,日志共有 N 行。
其中每一行的格式是:
ts id
表示在 ts 时刻编号 id 的帖子收到一个”赞”。现在小明想统计有哪些帖子曾经是”热帖”。如果一个帖子曾在任意一个长度为 D 的时间段内收到不少于 K 个赞,小明就认为这个帖子曾是”热帖”。
具体来说,如果存在某个时刻 T 满足该帖在 [T,T+D) 这段时间内(注意是左闭右开区间)收到不少于 K 个赞,该帖就曾是”热帖”。给定日志,请你帮助小明统计出所有曾是”热帖”的帖子编号。
输入格式:
第一行包含三个整数 N,D,K。
以下 N 行每行一条日志,包含两个整数 ts 和 id。
输出格式:
按从小到大的顺序输出热帖 id。
每个 id 占一行。
数据范围:
1≤K≤N≤1e5,
0≤ts,id≤1e5,
1≤D≤10000。输入样例:
7 10 2 0 1 0 10 10 10 10 1 9 1 100 3 100 3
输出样例:
1 3
1、2 题解关键思路与解答
我们大概叙述一下题目的意思:在一段时间内某个帖子的赞达到一定数量就被称为热帖。这道题中关键的就去维护一段时间段,看这个时间段内该帖子是否达到一定能够赞数。这个时候我们就需要两个指针(并不是真正的指针,是指变量)来维护这个时间段的区间了。我们先去要对输入的时间进行一个排序,然后再去维护这个区间,开一个记录状态的数组去看是否有达到热帖的。我们结合着代码一起理解一下:
#include<iostream>
#include<cstring>
#include<algorithm>
#include<cstdio>#define x first
#define y secondusing namespace std;typedef pair<int,int> PII;const int N=1e5+10;PII q[N];
int cnt[N];
bool st[N];int n,d,k;
int main()
{scanf("%d%d%d", &n, &d, &k);for(int i=0;i<n;i++)scanf("%d%d",&q[i].x,&q[i].y);sort(q,q+n);for(int i=0,j=0;i<n;i++){int id=q[i].y;cnt[id]++;//时间段区间while(q[i].x-q[j].x>=d){cnt[q[j].y]--;j++;}if(cnt[id]>=k)st[id]=true;}for(int i=0;i<N;i++)if(st[i])printf("%d\n",i);return 0;
}
二、献给阿尔吉侬的花束
2、1 题目描述
题目来源:《信息学奥赛一本通》
题目难度:简单
题目描述:阿尔吉侬是一只聪明又慵懒的小白鼠,它最擅长的就是走各种各样的迷宫。
今天它要挑战一个非常大的迷宫,研究员们为了鼓励阿尔吉侬尽快到达终点,就在终点放了一块阿尔吉侬最喜欢的奶酪。
现在研究员们想知道,如果阿尔吉侬足够聪明,它最少需要多少时间就能吃到奶酪。
迷宫用一个 R×C的字符矩阵来表示。
字符 S 表示阿尔吉侬所在的位置,字符 E 表示奶酪所在的位置,字符 # 表示墙壁,字符 . 表示可以通行。
阿尔吉侬在 1 个单位时间内可以从当前的位置走到它上下左右四个方向上的任意一个位置,但不能走出地图边界。
输入格式:
第一行是一个正整数 T,表示一共有 T 组数据。
每一组数据的第一行包含了两个用空格分开的正整数 R 和 C,表示地图是一个 R×C 的矩阵。
接下来的 R 行描述了地图的具体内容,每一行包含了 C 个字符。字符含义如题目描述中所述。保证有且仅有一个 S 和 E。
输出格式:
对于每一组数据,输出阿尔吉侬吃到奶酪的最少单位时间。
若阿尔吉侬无法吃到奶酪,则输出“oop!”(只输出引号里面的内容,不输出引号)。
每组数据的输出结果占一行。
数据范围:
1<T≤10,
2≤R,C≤200。输入样例:
3 3 4 .S.. ###. ..E. 3 4 .S.. .E.. .... 3 4 .S.. #### ..E.
输出样例:
5 1 oop!
2、2 题解关键思路与解答
首先我们要住注意的是本题的输入格式,要注意的是输入 0 0 时结束。我们要找到开始的位置和奶酪的位置。我们需要从开始位置出发,且是最小路径到达奶酪位置。这时我们可以想到洪水灌溉法(Flood Fill)。洪水灌溉法是指:dfs(深度优先搜索)和 bfs(宽度优先搜索)。dfs是采用递归的方法不断实现覆盖。dfs与bfs又有所不同,dfs写起来代码简单,bfs可以求出最短路径,各有优势。宽度优先是一层一层进行遍历的。是用队列进行维护实现的。队列是先进先出的原则。我们先把第一个数据入队。然后再循环进行维护。除去对头,入队与对头相关的点,直到队列为空。bfs有固定模板,通过本题,我们可以进行记一下。我们结合代码理解一下:
#include<iostream>
#include<algorithm>
#include<cstring>
#include<cstdio>
#include<queue>using namespace std;#define x first
#define y secondtypedef pair<int,int> PII;const int N=210;int n,m;int dist[N][N];
char g[N][N];int bfs(PII start,PII end)
{queue<PII> q;memset(dist,-1,sizeof dist); //初始dsit为-1,表示为没有走过该点dist[start.x][start.y]=0;q.push(start);while(q.size()){PII t=q.front();q.pop();int dx[4]={-1,1,0,0},dy[4]={0,0,-1,1};for(int i=0;i<4;i++){int x=t.x+dx[i],y=t.y+dy[i];if(x<0 ||x>=n || y<0 || y>=m)continue;if(g[x][y]=='#')continue;if(dist[x][y]!=-1)continue;dist[x][y]=dist[t.x][t.y]+1;if(g[x][y]=='E')return dist[x][y];q.push({x,y});}}return -1;
}
int main()
{int T;cin>>T;while(T--){scanf("%d%d",&n,&m);for(int i=0;i<n;i++)scanf("%s",g[i]);PII start,end;for(int i=0;i<n;i++)for(int j=0;j<m;j++)if(g[i][j]=='S')start={i,j};else if(g[i][j]=='E')end={i,j};int distance=bfs(start,end);if(distance==-1)puts("oop!");elseprintf("%d\n",distance);}return 0;
}
三、红与黑
3、1 题目描述
题目来源:《信息学奥赛一本通》
题目难度:简单
题目描述:有一间长方形的房子,地上铺了红色、黑色两种颜色的正方形瓷砖。你站在其中一块黑色的瓷砖上,只能向相邻(上下左右四个方向)的黑色瓷砖移动。请写一个程序,计算你总共能够到达多少块黑色的瓷砖。
输入格式:
输入包括多个数据集合。每个数据集合的第一行是两个整数 W 和 H,分别表示 x 方向和 y 方向瓷砖的数量。
在接下来的 H 行中,每行包括 W 个字符。每个字符表示一块瓷砖的颜色,规则如下
(1)‘.’:黑色的瓷砖;
(2)‘#’:红色的瓷砖;
(3)‘@’:黑色的瓷砖,并且你站在这块瓷砖上。该字符在每个数据集合中唯一出现一次。当在一行中读入的是两个零时,表示输入结束。
输出格式:
对每个数据集合,分别输出一行,显示你从初始位置出发能到达的瓷砖数(记数时包括初始位置的瓷砖)。
数据范围:
1≤W,H≤20。
输入样例:
6 9 ....#. .....# ...... ...... ...... ...... ...... #@...# .#..#. 0 0
输出样例:
45
3、2 题解关键思路与解答
该题我们就可以用dfs,也可以用bfs进行解答。但是用dfs时,我们要注意的是我们不需要有回复现场的操作,与第十四届蓝桥杯第三期模拟赛 C/C++ B组 原题与详解 填空题中的最大连通块类似。这道题目每个格子是一个状态,每个格子只会搜索一次,所以不需要恢复现场。我们分别看一下dfs与bfs的解题代码:
3、2、1 dfs题解代码
#include <cstring>
#include <iostream>
#include <algorithm>using namespace std;const int N = 25;int n, m;
char g[N][N];
bool st[N][N];int dx[4] = {-1, 0, 1, 0}, dy[4] = {0, 1, 0, -1};int dfs(int x, int y)
{int cnt = 1;st[x][y] = true;for (int i = 0; i < 4; i ++ ){int a = x + dx[i], b = y + dy[i];if (a < 0 || a >= n || b < 0 || b >= m) continue;if (g[a][b] != '.') continue;if (st[a][b]) continue;cnt += dfs(a, b);}return cnt;
}int main()
{while (cin >> m >> n, n || m){for (int i = 0; i < n; i ++ ) cin >> g[i];int x, y;for (int i = 0; i < n; i ++ )for (int j = 0; j < m; j ++ )if (g[i][j] == '@'){x = i;y = j;}memset(st, 0, sizeof st);cout << dfs(x, y) << endl;}return 0;
}
3、2、2 bfs题解答案
#include<bits/stdc++.h>using namespace std;#define x first
#define y secondconst int N =25;typedef pair<int,int> PII;char g[N][N];int n,m;int dx[4]={-1,1,0,0},dy[4]={0,0,-1,1};int bfs(int x,int y)
{queue<PII> q;q.push({x,y});g[x][y]='#';int res=0;while(q.size()){PII t=q.front();q.pop();res++;for(int i=0;i<4;i++){int a=t.x+dx[i],b=t.y+dy[i];if(a<0 || a>=n || b<0 || b>=m)continue;if(g[a][b]!='.')continue;q.push({a,b});g[a][b]='#';} }return res;
}
int main()
{while(cin>>m>>n,n||m){for(int i=0;i<n;i++)cin>>g[i];int x,y;for(int i=0;i<n;i++)for(int j=0;j<m;j++){if(g[i][j]=='@'){x=i;y=j;}}cout<<bfs(x,y)<<endl;}return 0;
}
四、交换瓶子
4、1 题目描述
题目来源:第七届蓝桥杯省赛C++B组,第七届蓝桥杯省赛JAVAA组
题目难度:简单
题目描述:有 N 个瓶子,编号 1∼N,放在架子上。比如有 5 个瓶子:
2 1 3 5 4
要求每次拿起 2 个瓶子,交换它们的位置。经过若干次后,使得瓶子的序号为:
1 2 3 4 5
对于这么简单的情况,显然,至少需要交换 2 次就可以复位。如果瓶子更多呢?你可以通过编程来解决。
输入格式:
第一行包含一个整数 N,表示瓶子数量。
第二行包含 N 个整数,表示瓶子目前的排列状况。
输出格式:
输出一个正整数,表示至少交换多少次,才能完成排序。
数据范围:
1≤N≤10000,
输入样例1:
5 3 1 2 5 4
输出样例1:
3
输入样例2:
5 5 4 3 2 1
输出样例2:
2
4、2 题解关键思路与解答
本题用到了图论的相关知识。我们把每个位置对应瓶子的编号进行连接,会形成相应的环。我们看题目中的例1:
我们需要做的是形成5个环,也就是自己指向自己。我们发先对一个含有两个及以上元素的环进行元素交换操作,一个环就会变成两个环。初始环越多,我们需要操作的次序越少,因为环中的元素很少。假如一个环中的元素有5个,我们最少的步数为4次。这样我们总结出规律是:最少需要操作的部数=元素个数-环的个数。我们看代码:
#include<iostream>
#include<algorithm>
#include<cstring>using namespace std;const int N=1e4+10;int b[N];
bool st[N];int main()
{int n;cin>>n;for(int i=1;i<=n;i++)cin>>b[i];int cnt=0;for(int i=1;i<=n;i++){if(!st[i]){cnt++; // 统计环的个数for(int j=i;!st[j];j=b[j])st[j]=true;}}cout<<n-cnt<<endl;return 0;
}
相关文章:

[蓝桥杯] 双指针、BFS和DFS与图论问题
文章目录 一、日志统计 1、1 题目描述 1、2 题解关键思路与解答 二、献给阿尔吉侬的花束 2、1 题目描述 2、2 题解关键思路与解答 三、红与黑 3、1 题目描述 3、2 题解关键思路与解答 3、2、1 dfs题解代码 3、2、2 bfs题解答案 四、交换瓶子 4、1 题目描述 4、2 题解关键思路与…...

编译原理陈火旺版第四章课后题答案
下面答案仅供参考! 1.考虑下面文法G1: (1) 消去 Q 的左递归。然后,对每个非终结符,写岀不带回溯的递归子程序。 (2) 经改写后的文法是否是LL(1)的?给出它的预测分析表。 2.对下面的文法G: P→(E)lalblΛ (1)计算这个文法的每个非…...

【LeetCode】剑指 Offer(25)
目录 题目:剑指 Offer 49. 丑数 - 力扣(Leetcode) 题目的接口: 解题思路: 代码: 过啦!!! 写在最后: 题目:剑指 Offer 49. 丑数 - 力扣&…...

【数据结构】链表OJ
Yan-英杰的主页 悟已往之不谏 知来者之可追 目录 编辑 编辑二、分享:OJ调试技巧 编辑三、链表的中间结点 编辑四、链表中倒数第k个结点 一、移除链表元素 示例 1: 输入:head [1,2,6,3,4,5,6], val 6 输出:[1,2,3,4,…...

电子工程师必须掌握的硬件测试仪器,你确定你都掌握了?
目录示波器示例1:测量示波器自带的标准方波信号输出表笔认识屏幕刻度认识波形上下/左右移动上下/左右刻度参数调整通道1的功能界面捕获信号设置Menu菜单触发方式触发电平Cursor按钮捕捉波形HLEP按钮参考资料频谱分析仪器信号发生器示波器 示例1:测量示波…...
高速PCB设计指南系列(四)
第二篇 抗干扰3(部分) 3 提高敏感器件的抗干扰性能 提高敏感器件的抗干扰性能是指从敏感器件这边考虑尽量减少对干扰噪声 的拾取,以及从不正常状态尽快恢复的方法。 提高敏感器件抗干扰性能的常用措施如下: (1&…...

ODrive入门配置
目录一、驱动板说明二、安装python三、安装odrivetool四、接线五、zadig设置SimpleFOC、ODrive和VESC教程链接汇总:请点击一、驱动板说明 ODrive 硬件版本:V3.6-56V, 工作电压:12V-56V, 工作电流:60A ODri…...
快速测试两台服务器间的网速(ChatGPT回复)
如何使用iperf3测试从远程服务器下载文件速度 在进行网络性能测试时,了解服务器之间的带宽和延迟是非常重要的。iperf3是一种用于测量网络性能的工具,可以帮助我们测试从远程服务器下载文件的速度。本文将介绍如何在本地计算机上使用iperf3测试从远程服…...

彻底搞懂nodejs事件循环
nodejs是单线程执行的,同时它又是基于事件驱动的非阻塞IO编程模型。这就使得我们不用等待异步操作结果返回,就可以继续往下执行代码。当异步事件触发之后,就会通知主线程,主线程执行相应事件的回调。 以上是众所周知的内容。今天…...

Linux基础命令大全(下)
♥️作者:小刘在C站 ♥️个人主页:小刘主页 ♥️每天分享云计算网络运维课堂笔记,努力不一定有收获,但一定会有收获加油!一起努力,共赴美好人生! ♥️夕阳下,是最美的绽放࿰…...

Matplotlib从入门到精通05-样式色彩秀芳华
Matplotlib从入门到精通05-样式色彩秀芳华总结Matplotlib从入门到精通05-样式色彩秀芳华导入依赖一、matplotlib的绘图样式(style)1.matplotlib预先定义样式2.用户自定义stylesheet3.设置rcparams二、matplotlib的色彩设置(color)…...

< CSS小技巧:那些不常用,却很惊艳的CSS属性 >
文章目录👉 前言👉 一. background-clip: text - 限制背景显示(裁剪)👉 二. user-select - 控制用户能否选中文本👉 三. :focus-within 伪类👉 四. gap - 网格 / 弹性布局间隔设置👉…...

GPT-4 重磅发布,用户直呼:强得离谱
ChatGPT沉寂了一会,OpenAI 的新“核弹”又来了,GPT-4,并且它还非常擅长编码。闲话不提,直捣黄龙。 OpenAI 宣布发布 GPT-4 ChatGPT-4这是 OpenAI 努力扩展深度学习的最新里程碑,GPT-4 是一个大型多模态模型。 据悉&a…...

【JavaSE】知识点总结(3)
目录 一、类定义和使用 1. 类的定义 2. 类的实例化 3. 构造方法 构造方法的重载 二、this关键字 三、 static 修饰属性 四、封装 2. getter与setter 五、继承 1. 继承的语法 2. 子类中访问父类 3. 关于继承原则 4. super关键字 5. super和this 6. protected 关键…...

MySQL基础(三)聚合函数、子查询
目录 聚合函数 AVG/SUM/MAX/MIN COUNT函数 GROUP BY HAVING having和where的区别 SELECT的执行过程 子查询 单行子查询vs多行子查询 单行子查询 多行子查询 关联子查询 EXISTS 与 NOT EXISTS关键字 聚合函数 聚合函数作用于一组数据,并对一组数据返回一个…...

深度学习数据集处理基础内容——xml和json文件详解
文章目录一、xml文件1.1 什么是 XML?1.2XML 和 HTML 之间的差异1.3XML 不会做任何事情1.4通过 XML 您可以发明自己的标签1.5XML 不是对 HTML 的替代1.6XML 无所不在二、json文件基本的JSON结构体类型(共享部分)三、转COCO数据集3.1 info3.2 l…...

蓝桥杯基础技能训练
51单片机系统浓缩图 1. HC138译码器 用3个输入引脚,实现8个输出引脚,而且这个八个输出引脚中只要一个低电平,所以我们只需要记住真值表就行 #include "reg52.h" sbit HC138_A P2^5; sbit HC138_B P2^6; sbit HC…...

【Kubernetes】第二十八篇 - 实现自动构建部署
一,前言 上一篇,介绍了 Deployment、Service 的创建,完成了前端项目的构建部署; 希望实现:推送代码 -> 自动构建部署-> k8s 滚动更新; 本篇,实现自动构建部署 二,推送触发构…...
蓝桥杯刷题第十天
第一题:裁纸刀问题描述本题为填空题,只需要算出结果后,在代码中使用输出语句将所填结果输出即可。小蓝有一个裁纸刀,每次可以将一张纸沿一条直线裁成两半。小蓝用一张纸打印出两行三列共 6 个二维码,至少使用九次裁出来…...

网络安全缓冲区溢出与僵尸网络答题分析
一、缓冲区溢出攻击 缓冲区溢出是指当计算机向缓冲区内填充数据位数时超过了缓冲区本身的容量,溢出的数据覆盖在合法数据上。理想的情况是:程序会检查数据长度,而且并不允许输入超过缓冲区长度的字符。但是绝大多数程序都会假设数据长度总是…...

华为云AI开发平台ModelArts
华为云ModelArts:重塑AI开发流程的“智能引擎”与“创新加速器”! 在人工智能浪潮席卷全球的2025年,企业拥抱AI的意愿空前高涨,但技术门槛高、流程复杂、资源投入巨大的现实,却让许多创新构想止步于实验室。数据科学家…...
Leetcode 3576. Transform Array to All Equal Elements
Leetcode 3576. Transform Array to All Equal Elements 1. 解题思路2. 代码实现 题目链接:3576. Transform Array to All Equal Elements 1. 解题思路 这一题思路上就是分别考察一下是否能将其转化为全1或者全-1数组即可。 至于每一种情况是否可以达到…...

PPT|230页| 制造集团企业供应链端到端的数字化解决方案:从需求到结算的全链路业务闭环构建
制造业采购供应链管理是企业运营的核心环节,供应链协同管理在供应链上下游企业之间建立紧密的合作关系,通过信息共享、资源整合、业务协同等方式,实现供应链的全面管理和优化,提高供应链的效率和透明度,降低供应链的成…...

visual studio 2022更改主题为深色
visual studio 2022更改主题为深色 点击visual studio 上方的 工具-> 选项 在选项窗口中,选择 环境 -> 常规 ,将其中的颜色主题改成深色 点击确定,更改完成...

NFT模式:数字资产确权与链游经济系统构建
NFT模式:数字资产确权与链游经济系统构建 ——从技术架构到可持续生态的范式革命 一、确权技术革新:构建可信数字资产基石 1. 区块链底层架构的进化 跨链互操作协议:基于LayerZero协议实现以太坊、Solana等公链资产互通,通过零知…...
Linux离线(zip方式)安装docker
目录 基础信息操作系统信息docker信息 安装实例安装步骤示例 遇到的问题问题1:修改默认工作路径启动失败问题2 找不到对应组 基础信息 操作系统信息 OS版本:CentOS 7 64位 内核版本:3.10.0 相关命令: uname -rcat /etc/os-rele…...
libfmt: 现代C++的格式化工具库介绍与酷炫功能
libfmt: 现代C的格式化工具库介绍与酷炫功能 libfmt 是一个开源的C格式化库,提供了高效、安全的文本格式化功能,是C20中引入的std::format的基础实现。它比传统的printf和iostream更安全、更灵活、性能更好。 基本介绍 主要特点 类型安全:…...
Kubernetes 网络模型深度解析:Pod IP 与 Service 的负载均衡机制,Service到底是什么?
Pod IP 的本质与特性 Pod IP 的定位 纯端点地址:Pod IP 是分配给 Pod 网络命名空间的真实 IP 地址(如 10.244.1.2)无特殊名称:在 Kubernetes 中,它通常被称为 “Pod IP” 或 “容器 IP”生命周期:与 Pod …...
文件上传漏洞防御全攻略
要全面防范文件上传漏洞,需构建多层防御体系,结合技术验证、存储隔离与权限控制: 🔒 一、基础防护层 前端校验(仅辅助) 通过JavaScript限制文件后缀名(白名单)和大小,提…...

PydanticAI快速入门示例
参考链接:https://ai.pydantic.dev/#why-use-pydanticai 示例代码 from pydantic_ai import Agent from pydantic_ai.models.openai import OpenAIModel from pydantic_ai.providers.openai import OpenAIProvider# 配置使用阿里云通义千问模型 model OpenAIMode…...