CSP认证准备第三天-差分及第36次CCF认证(BFS)

基础知识参考:

csp突击前两题常用算法代码_ccf csp常用优化算法-CSDN博客

差分

什么是差分数组?

差分数组是原数组相邻元素之间的差值构成的数组。对于原数组 a,其差分数组 b 定义为:

  • b[1] = a[1] (假设 a[0] = 0)

  • b[i] = a[i] - a[i-1] (对于 i > 1)

为什么差分数组有用?

差分数组的神奇之处在于:对原数组的区间加减操作可以转化为对差分数组的两个单点操作

差分例题

一个长度为n的整数序列。
对其进行m次操作,每个操作包含三个整数l, r, c,表示将序列中[l, r]之间的每个数加上c。
请你输出进行完所有操作后的序列。

###输入格式
第一行包含两个整数n和m。
第二行包含n个整数,表示整数序列。
接下来m行,每行包含三个整数l,r,c,表示一个操作。
###输出格式
共一行,包含n个整数,表示最终序列。
###数据范围
1≤n,m≤100000,
1≤l≤r≤n,
−1000≤c≤1000,
−1000≤整数序列中元素的值≤1000

如果用暴力做法每次都循环一遍区间的值然后操作的话时间肯定会超限
所以用一种巧妙地方法就是构造差分数组,
对区间[l,r]进行+c操作时只需要在差分数组里对b[l] += c,b[r+1] -= c
然后累和恢复数组时就可对区间内所有数+c

区间更新原理

当我们要对原数组 a 的区间 [l, r] 中每个元素加 c 时:

  1. 对差分数组 b[l] += c:这使得 a[l] 及之后的所有元素都增加了 c

  2. 对差分数组 b[r+1] -= c:这抵消了 a[r+1] 及之后元素的增加,使得只有 [l, r] 区间内的元素增加了 c

恢复原数组

通过计算差分数组的前缀和,我们可以恢复出更新后的原数组:

  • a'[i] = b[1] + b[2] + ... + b[i]

或者下标直接从1开始比较好:

#include<iostream>
using namespace std;
int a[100010], b[100010];
int main(){int n, m;cin>>n>>m;for(int i = 1; i <= n; i ++){cin>>a[i];b[i] = a[i] - a[i - 1];	//构造差分数组}while(m --){int l, r, c;cin>>l>>r>>c;b[l] += c;	b[r + 1] -= c;}for(int i = 1; i <= n; i ++){b[i] = b[i] + b[i - 1];cout<<b[i]<<" ";}return 0;
}

第36次CCF认证-第四题

 参考题解:

CCF-CSP第36次认证第四题——跳房子【NA!巧妙利用BFS】_csp跳房子-CSDN博客

第36次ccf-csp题解(思维) - devoteeing - 博客园

  应该属于经典题,BFS寻找最短路径,我还是不太熟悉,需要多多刷题啊。依稀记得当时有过短短的挣扎,然而确实是练少了,真的想不起来。(OK啊,后面我要系统练一下搜索算法了)

  好吧,承认我读完题目之后真的毫无头绪,这种求最优解法的题目我真的束手无措。

BFS

参考资料:

BFS(图论) - OI Wiki

第十三章 DFS与BFS(保姆级教学!!超级详细的图示!!)_dfs bfs-CSDN博客

BFS 全称是 Breadth First Search,中文名是宽度优先搜索,也叫广度优先搜索。

是图上最基础、最重要的搜索算法之一。

所谓宽度优先。就是每次都尝试访问同一层的节点。 如果同一层都访问完了,再访问下一层。

这样做的结果是,BFS 算法找到的路径是从起点开始的 最短 合法路径。换言之,这条路径所包含的边数最小。

在 BFS 结束时,每个节点都是通过从起点到该点的最短路径访问的。

算法过程可以看做是图上火苗传播的过程:最开始只有起点着火了,在每一时刻,有火的节点都向它相邻的所有节点传播火苗。

例题1-走迷宫

#include<iostream>
#include<cstring>
#include<queue>
using namespace std;
const int N=110;
typedef pair<int,int> PII;
int map[N][N],mark[N][N];
int dx[4]={-1,0,1,0},dy[4]={0,1,0,-1},n,m,ans;
void bfs()
{memset(mark,-1,sizeof mark);queue<PII>q;q.push({0,0});mark[0][0]=0;while(!q.empty()){PII top=q.front();for(int i=0;i<4;i++){int nex=top.first+dx[i],ney=top.second+dy[i];if(nex>=0&&nex<n&&ney>=0&&ney<m&&mark[nex][ney]==-1&&map[nex][ney]==0){mark[nex][ney]=mark[top.first][top.second]+1;q.push({nex,ney});}}q.pop();}cout<<mark[n-1][m-1];
}
int main()
{cin>>n>>m;for(int i=0;i<n;i++){for(int j=0;j<m;j++){scanf("%d",&map[i][j]);}}bfs();
}

BFS模版

void bfs(int u) {while (!Q.empty()) Q.pop();Q.push(u);vis[u] = 1;d[u] = 0;p[u] = -1;while (!Q.empty()) {u = Q.front();Q.pop();for (int i = head[u]; i; i = e[i].nxt) {if (!vis[e[i].to]) {Q.push(e[i].to);vis[e[i].to] = 1;d[e[i].to] = d[u] + 1;p[e[i].to] = u;}}}
}void restore(int x) {vector<int> res;for (int v = x; v != -1; v = p[v]) {res.push_back(v);}std::reverse(res.begin(), res.end());for (int i = 0; i < res.size(); ++i) printf("%d", res[i]);puts("");
}

其中,

图的存储方式(链式前向星)

head[u] 和 e[i] 是链式前向星(一种图的邻接表存储方式)的关键部分:

  • head[u]:存储节点 u 的第一条边的编号(索引)。

  • e[i]:是一个结构体数组,存储第 i 条边的信息,通常包括:

    • e[i].to:这条边指向的节点(终点)。

    • e[i].nxt:下一条与 u 相连的边的编号(类似于链表中的 next 指针)

BFS应用

例题2-密室

问题 - 173B - Codeforces

一个n*m的图,现在有一束激光从左上角往右边射出,每遇到 '#',你可以选择光线往四个方向射出,或者什么都不做,问最少需要多少个 '#' 往四个方向射出才能使光线在第n行往右边射出。

此题目正解不是 0-1BFS,但是适用 0-1BFS,减小思维强度,赛时许多大佬都是这么做的。

做法很简单,一个方向射出不需要花费(0),而往四个方向射出需要花费(1),然后直接来就可以了。

#include <deque>
#include <iostream>
using namespace std;constexpr int INF = 1 << 29;
int n, m;
char grid[1001][1001];
int dist[1001][1001][4];
int fx[] = {1, -1, 0, 0};
int fy[] = {0, 0, 1, -1};
deque<int> q;  // 双端队列void add_front(int x, int y, int dir, int d) {  // 向前方加if (d < dist[x][y][dir]) {dist[x][y][dir] = d;q.push_front(dir);q.push_front(y);q.push_front(x);}
}void add_back(int x, int y, int dir, int d) {  // 向后方加if (d < dist[x][y][dir]) {dist[x][y][dir] = d;q.push_back(x);q.push_back(y);q.push_back(dir);}
}int main() {cin >> n >> m;for (int i = 0; i < n; i++) cin >> grid[i];for (int i = 0; i < n; i++)for (int j = 0; j < m; j++)for (int k = 0; k < 4; k++) dist[i][j][k] = INF;add_front(n - 1, m - 1, 3, 0);while (!q.empty()) {  // 具体搜索的过程,可以参考上面写的题解int x = q[0], y = q[1], dir = q[2];q.pop_front();q.pop_front();q.pop_front();int d = dist[x][y][dir];int nx = x + fx[dir], ny = y + fy[dir];if (nx >= 0 && nx < n && ny >= 0 && ny < m)add_front(nx, ny, dir, d);  // 判断条件if (grid[x][y] == '#')for (int i = 0; i < 4; i++)if (i != dir) add_back(x, y, i, d + 1);}if (dist[0][0][3] == INF)cout << -1 << endl;elsecout << dist[0][0][3] << endl;return 0;
}

习题

  • 「NOIP2017」奶酪

双端队列 BFS:

  • CF1063B. Labyrinth
  • CF173B. Chamber of Secrets
  • 「BalticOI 2011 Day1」打开灯泡 Switch the Lamp On

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

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

相关文章

[案例四] 智能填写属性工具(支持装配组件还有建模实体属性的批量创建、编辑)

论文盲审结果要出来了,渣渣超没有心情继续写了,过一段时间再说吧,今天宣布五一结束,哈哈哈。写完这篇博客开始搞科研了,有时间再进NX开发学习。本次案例主要是对上次导出自动导出BOM的一个前处理,要想导出属性,首先的有属性。于是本着学习的态度进行制作,可能有些功能有…

四核RK3566多媒体控制板技术分享(RK3566如何实现7个串口同时进行)

四核RK3566多媒体控制板技术分享: 今天分享一款近期接触到的四核RK3566多媒体控制板&#xff08;产品型号&#xff1a;ZK-R36A&#xff09;&#xff0c;这款产品在工业控制和智能设备领域有不错的表现&#xff0c;特此整理了一些技术参数供大家参考。 产品概述: 这款控制板采用…

多线程代码案例-1 单例模式

单例模式 单例模式是开发中常见的设计模式。 设计模式&#xff0c;是我们在编写代码时候的一种软性的规定&#xff0c;也就是说&#xff0c;我们遵守了设计模式&#xff0c;代码的下限就有了一定的保证。设计模式有很多种&#xff0c;在不同的语言中&#xff0c;也有不同的设计…

【计算机组成原理】第二部分 存储器--分类、层次结构

文章目录 分类&层次结构0x01 分类按存储介质分类按存取方式分类按在计算机中的作用分类 0x02 层次结构 分类&层次结构 0x01 分类 按存储介质分类 半导体存储器磁表面存储器磁芯存储器光盘存储器 按存取方式分类 存取时间与物理地址无关&#xff08;随机访问&#…

迅为RK3588开发板安卓GPIO调用APP运行测试

将网盘上的安卓工程文件复制到 Windows 电脑上。确保工程路径中使用英文字符&#xff0c;不包含中文。接着&#xff0c;启动 Android Studio&#xff0c;点击“Open”按钮选择应用工程文件夹&#xff0c;然后点击“OK”。由于下载 Gradle 和各种 Jar 包可能需要一段时间&#x…

BFS算法篇——打开智慧之门,BFS算法在拓扑排序中的诗意探索(下)

文章目录 引言一、课程表1.1 题目链接&#xff1a;https://leetcode.cn/problems/course-schedule/description/1.2 题目分析&#xff1a;1.3 思路讲解&#xff1a;1.4 代码实现&#xff1a; 二、课程表||2.1 题目链接&#xff1a;https://leetcode.cn/problems/course-schedul…

计数循环java

import java.util.Scanner;public class Hello {public static void main(String[] args) {Scanner in new Scanner(System.in);int count 10;while(count > 0) {count count -1;System.out.println(count);}System.out.println(count);System.out.println("发射&am…

11. CSS从基础样式到盒模型与形状绘制

在前端开发中&#xff0c;CSS&#xff08;层叠样式表&#xff09;是控制网页样式和布局的核心技术。整理了关于 CSS 基础样式、文本样式、盒模型以及形状绘制的一些心得。以下是详细的学习笔记。 一、基础样式设置 1. 字体样式 字体样式是网页视觉呈现的重要组成部分&#xf…

双种群进化算法:动态约束处理与资源分配解决约束多目标优化问题

双种群进化算法&#xff1a;动态约束处理与资源分配解决约束多目标优化问题 一、引言 约束多目标优化问题&#xff08;CMOPs&#xff09;在工程设计、资源分配等领域广泛存在&#xff0c;其核心是在满足多个约束条件的同时优化多个目标函数。传统方法往往难以平衡约束满足与目…

【Qt】pro工程文件转CMakeLists文件

1、简述 Qt6以后默认使用cmake来管理工程,之前已经一直习惯使用pro,pro的语法确实很简单、方便。 很多项目都是cmake来管理,将它们加入到Qt项目中,cmake确实是大势所趋。比如,最近将要开发的ROS项目,也是使用的cmake语法。 以前总结的一些Qt代码,已经编写成pro、pri等…

手机换地方ip地址会变化吗?深入解析

在移动互联网时代&#xff0c;我们经常带着手机穿梭于不同地点&#xff0c;无论是出差旅行还是日常通勤。许多用户都好奇&#xff1a;当手机更换使用地点时&#xff0c;IP地址会随之改变吗&#xff1f;本文将深入解析手机IP地址的变化机制&#xff0c;帮助您全面了解这一常见但…

【Canda】常用命令+虚拟环境创建到选择

目录 一、conda常用命令 二、conda 环境 2.1 创建虚拟环境 2.2 conda环境切换 2.3 查看conda环境 2.4 删除某个conda环境 2.5 克隆环境 三、依赖包管理 3.1 安装命令 3.2 更新包 3.3 卸载包 3.4 查看环境中所有包 3.5 查看某个包的版本信息 3.6 搜索包 四、环境…

目标检测任务常用脚本1——将YOLO格式的数据集转换成VOC格式的数据集

在目标检测任务中&#xff0c;不同框架使用的标注格式各不相同。常见的框架中&#xff0c;YOLO 使用 .txt 文件进行标注&#xff0c;而 PASCAL VOC 则使用 .xml 文件。如果你需要将一个 YOLO 格式的数据集转换为 VOC 格式以便适配其他模型&#xff0c;本文提供了一个结构清晰、…

Python作业练习2

任务简述 if_name__main_的含义&#xff0c;why? 问题解答 在Python中&#xff0c;if __name__ __main__:是一种常见的惯用法&#xff0c;用于检查当前模块是否是主程序入口点。要理解其含义和用途&#xff0c;首先需要了解两个概念&#xff1a; 1. __name__: 这是一个特…

ppy/osu构建

下载 .NET (Linux、macOS 和 Windows) | .NET dotnet还行 构建&#xff1a;f5 运行&#xff1a;dotnet run --project osu.Desktop -c Debug

NY182NY183美光固态颗粒NY186NY188

NY182NY183美光固态颗粒NY186NY188 在存储技术的竞技场上&#xff0c;美光科技&#xff08;Micron&#xff09;始终扮演着革新者的角色。其NY系列固态颗粒凭借前沿的3D NAND架构和精准的工艺控制&#xff0c;成为企业级存储和数据中心的关键支柱。本文将围绕NY182、NY183、NY1…

C++的历史与发展

目录 一、C 的诞生与早期发展 &#xff08;一&#xff09;C 语言的兴起与局限 &#xff08;二&#xff09;C 的雏形&#xff1a;C with Classes &#xff08;三&#xff09;C 命名与早期特性丰富 二、C 的主要发展历程 &#xff08;一&#xff09;1985 年&#xff1a;经典…

DedeCMS-Develop-5.8.1.13-referer命令注入研究分析 CVE-2024-0002

本次文章给大家带来代码审计漏洞挖掘的思路&#xff0c;从已知可控变量出发或从函数功能可能照成的隐患出发&#xff0c;追踪参数调用及过滤。最终完成代码的隐患漏洞利用过程。 代码审计挖掘思路 首先flink.php文件的代码执行逻辑&#xff0c;可以使用php的调试功能辅助审计 …

计算机网络|| 常用网络命令的作用及工作原理

1.hostname 作用&#xff1a;显示计算机的完整计算机名的主机名部分。仅当 Internet 协议 (TCP/IP) 协议作为组件安装在网络的网络适配器的属性中时&#xff0c;此命令才可用。 2.ping 作用&#xff1a; 1.用来检测网络的连通情况和分析网络速度 2.根据域名得到服务器 IP …

用户态到内核态:Linux信号传递的九重门(二)

1. 保存信号 1.1. 信号其他相关常见概念 实际执⾏信号的处理动作称为信号递达(Delivery)。 信号从产⽣到递达之间的状态,称为信号未决(Pending)。 进程可以选择阻塞 (Block )某个信号。 被阻塞的信号产⽣时将保持在未决状态,直到进程解除对此信号的阻塞,才执⾏递达的动作。 1.…