当前位置: 首页 > news >正文

算法提升第一章:基础算法总结

        Hello大家好!我是但凡。很高兴为大家带来我的全新系列文章:算法提升篇。

        今天我在这里总结一些基础算法,旨在帮助大家复习算法大纲,从宏观角度看待各种算法。注意,这个系列的文章只适合大家用来复习和总览各种算法,并不是为新手和从没有接触过算法的小白而准备的基础内容讲解。

        当然了这篇文章也可以用作新人对于算法的基础认识,但只用过这篇文章就掌握基础算法是不太可能的

        每个算法我只是简单概括一下,并附赠一些练习题。其中每个题目我都做了详细的注释。注释中有很多算法原理的记忆与理解。希望大家看看。

1、模拟

        顾名思义,就是根据题意用编程语言把题中描述的操作模拟出来。这类题目一般不会用到什么复杂的操作,通常就是考察数组,循环,条件语句的使用。是一类比较简单的算法题。

        我在这给出两道:题海拾贝:蛇形输入_1 ddcfdc-cdcddcdcrdcccddddcdccfcd-dcddscddccfdccff-CSDN博客

题海拾贝:P1098 [NOIP2007 提高组] 字符串的展开-CSDN博客

2、高精度

        高精度算法是指无法用自带的数据类型记录下来的数的加减乘除运算。这类算法题就是想办法用数组,模拟手算的方法来计算数据。其实这种题只有加减乘除四道,所以大家完全可以把这四道题当做模板背下来。

题海拾贝:【高精度】加法-CSDN博客

题海拾贝:【高精度】减法-CSDN博客

题海拾贝:【高精度】乘法-CSDN博客

题海拾贝:【高精度】除法-CSDN博客

3、枚举

3.1、普通枚举

        个人理解就是暴力穷举。把所有的情况都穷举出来。但是需要注意对于一道题目可能有多个能够穷举的对象,我们需要找到穷举次数最少得那种方案。并且能够通过各种规律减少循环的次数。

        举个最简单的例子,在判断是否是质数的程序中,我们就不用判断一个偶数(除2以外)是不是质数。因为偶数不可能是质数(除2以外)。这样就减少了消耗时间。

题海拾贝:【枚举】P2010 [NOIP 2016 普及组] 回文日期-CSDN博客

题海拾贝:扫雷-CSDN博客

3.2、二进制枚举

        这种枚举策略是我们在学习C语言基础和数据结构时没有遇到过的。

        比方说现在有个抽数游戏,有n个数,每个数都有抽与不抽两个选择。我们怎么枚举出所有选择呢?难道写n个for循环吗?可问题是根本就写不出n个for循环,我们不知道写多少个。那我们就可以用二进制枚举,检测从0到1<<n-1每个数的0和1。0就是不选,1就是选。这样只用两个for循环就够了。

        来两道题感受一下:

        题海拾贝:力扣 78.子集-CSDN博客

        题海拾贝:P10449 费解的开关-CSDN博客

        UVA11464 Even Parity.txt · 王子萌/练习代码 - Gitee.com

        有一些题目我并没有上传的csdn,所以放的是我的gitee代码仓的链接。

4、前缀和

        这个算是比较重要的基础算法了。前缀和分为一维前缀和和二维前缀和。这类算法主要用于处理或者说优化区间求和的问题。说直白点就是我们要求那一段数据的和并不需要在把他们一个个数加起来算出来了。而是在读入数据的时候提前处理好。

        一维前缀和还是比较简单的:

        P1115 最大子段和.txt · 王子萌/练习代码 - Gitee.com

        二维前缀和相比一维还是有些难度的。我们需要在理解的基础上记住求解二维前缀和的公式:

       牛客.二位前缀名.txt · 王子萌/练习代码 - Gitee.com              https://gitee.com/ZiMeng-Wang/practice-code/blob/master/P2280%20[HNOI2003]%20%E6%BF%80%E5%85%89.txt

 5、差分     

        差分其实就是记录每相邻的两个数之间的差值。主要用于求解一段区间统一加减某个整数的操作。差分算法主要分为这几步:

        1、构建差分数组

        2、修改差分数组

        3、询问

        4、还原差分数组。

        需要注意的是只有在所有操作之后才能还原差分数组。

        P3406海底高铁.txt · 王子萌/练习代码 - Gitee.com

        牛客 模版差分.txt · 王子萌/练习代码 - Gitee.com

        二维差分同样有一些公式类的东西需要理解后记忆。

        牛客模版二维差分.txt · 王子萌/练习代码 - Gitee.com

        P3397 地毯.txt · 王子萌/练习代码 - Gitee.com

6、双指针

        我们之前在C语言基础和数据结构篇章使用过双指针。一般都是一个指针或标记从数组开头往后遍历,另一个从后往前。

        但我们这里的双指针又叫滑动窗口,是⼀种优化暴力枚举策略的手段,和之前的不太一样。

        当我们发现在两层for循环的暴力枚举过程中,两个指针是可以不回退的,此时我们就可以利用两个指针不回退的性质来优化时间复杂度。

        UVA11572唯一的雪花.txt · 王子萌/练习代码 - Gitee.com

        P1638 逛画展.txt · 王子萌/练习代码 - Gitee.com

        题海拾贝:【双指针】丢手绢-CSDN博客

7、二分算法

7.1二分查找

        这个算法也是基础算法里比较重要的。说通白点就是高效率的查找一个数组中的某个数。在之前我们其实也接触过。掌握这个算法并不难,首先我们应该背过查找数组中数字左右区间的两个模版:

        二分查找模板.txt · 王子萌/练习代码 - Gitee.com

        这两个模版是伴随着我们的二分学习路程中的。

        需要注意的是,想要使用二分查找,这个数组必须是有序的

其实c++的STL中有二分查找:

1. lower_bound :大于等于x的最小元素,返回的是迭代器;时间复杂度:O(log N) 。

2. upper_bound :大于x的最小元素,返回的是迭代器。时间复杂度:O(log N) 。 二者均采用二分实现。

        但是STL中的二分查找只能适⽤于"在有序的数组中查找",如果是二分答案就不能使用。因此还是需要记忆二分模板。

        P1102 A-B 数对.txt · 王子萌/练习代码 - Gitee.com

        牛客 牛可乐和魔法封印.txt · 王子萌/练习代码 - Gitee.com

        P1678 烦恼的志愿.txt · 王子萌/练习代码 - Gitee.com

7.2 二分答案

        二分答案适用于解决最大值最小或最小值最大的问题。只要题目中出现最大值最小或者最小值最大就想想二分答案是否可行。二分答案可行的题目一定具有二段性,意思就是,比方说现在有一个数组,所有大于ret这个数的都不行,所有小于ret这个数的都满足答案。我们要查找的是满足条件的极限值,也就是小于ret的最大值。这就是二段性。我们解决的这个问题就叫最小值最大问题。

        来几道题感受一下:

        https://gitee.com/ZiMeng-Wang/practice-code/blob/master/P2678%20[NOIP%202015%20%E6%8F%90%E9%AB%98%E7%BB%84]%20%E8%B7%B3%E7%9F%B3%E5%A4%B4.txt

         P1873 砍树.txt · 王子萌/练习代码 - Gitee.com

         二分答案P2440 木材加工.txt · 王子萌/练习代码 - Gitee.com

8、贪心

        贪心这个算法比较逆天,他没有统一的模板去背,每拿到一个题都是新题,面对贪心的题大概率有三种:一,完全没思路。二,有思路,代码不会写。三、有思路,写出来了,但是贪的根本就不对。当然了我希望大家都能做对哈哈。

        贪心这个算法,就是对于多步骤问题,我们每一步都去拿最优结果。比如经典的用一百元换零钱,我们先用50换,换完50了再用20,换完20的了再用10块去凑,直到最后再用一块去凑。这就是一道简单的贪心思维题。

        贪心这部分分为四种类型,但贪心的题目远远不止四种。这部分题只能说是多看,多练,多想,多总结。

8.1、简单贪心

        P10452 货仓选址.txt · 王子萌/练习代码 - Gitee.com

       贪心P1115 最大子段和.txt · 王子萌/练习代码 - Gitee.com

        https://gitee.com/ZiMeng-Wang/practice-code/blob/master/P1094%20[NOIP%202007%20%E6%99%AE%E5%8F%8A%E7%BB%84]%20%E7%BA%AA%E5%BF%B5%E5%93%81%E5%88%86%E7%BB%84.txt

         https://gitee.com/ZiMeng-Wang/practice-code/blob/master/P1056%20[NOIP%202008%20%E6%99%AE%E5%8F%8A%E7%BB%84]%20%E6%8E%92%E5%BA%A7%E6%A4%85.txt

        牛客矩阵消除游戏.txt · 王子萌/练习代码 - Gitee.com 

8.2、推公式 

        https://gitee.com/ZiMeng-Wang/practice-code/blob/master/P1012%20[NOIP%201998%20%E6%8F%90%E9%AB%98%E7%BB%84]%20%E6%8B%BC%E6%95%B0.txt

         https://gitee.com/ZiMeng-Wang/practice-code/blob/master/P2878%20[USACO07JAN]%20Protecting%20the%20Flowers%20S.txt

        https://gitee.com/ZiMeng-Wang/practice-code/blob/master/P1842%20[USACO05NOV]%20%E5%A5%B6%E7%89%9B%E7%8E%A9%E6%9D%82%E6%8A%80.txt 

8.3、哈夫曼编码

        模版哈夫曼编码.txt · 王子萌/练习代码 - Gitee.com

        https://gitee.com/ZiMeng-Wang/practice-code/blob/master/P1090%20[NOIP%202004%20%E6%8F%90%E9%AB%98%E7%BB%84]%20%E5%90%88%E5%B9%B6%E6%9E%9C%E5%AD%90.txt

8.4、区间问题

        P1803 凌乱的yyy 线段覆盖.txt · 王子萌/练习代码 - Gitee.com

        UVA1193 Radar Installation.txt · 王子萌/练习代码 - Gitee.com

         https://gitee.com/ZiMeng-Wang/practice-code/blob/master/P2887%20[USACO07NOV]%20Sunscreen%20G.txt

        贪心这块虽然恶心但还是应该提起注意的,毕竟这也是很重要的算法。

9、倍增

        这个倍增就比较简单了昂,他主要是解决快速加或快速乘的问题。举个例子我们要求二的十一次方,把十一的二进制写出来,用每一位的权重乘上当前位的数(1 0)最后在乘起来,就能够快速算出二的十一次方。

        P1226 【模板】快速幂.txt · 王子萌/练习代码 - Gitee.com

        P10446 64位整数乘法.txt · 王子萌/练习代码 - Gitee.com

10、离散化

        离散化适用于处理,数据每个数都很大,但是数的数量很少了的存储问题。核心思想就是,把这堆数,从小到大的无重复的放到离散化数组里。

        离散化模板一去重加二分.txt · 王子萌/练习代码 - Gitee.com

        离散化模板二哈希表.txt · 王子萌/练习代码 - Gitee.com

        https://gitee.com/ZiMeng-Wang/practice-code/blob/master/P3740%20[HAOI2014]%20%E8%B4%B4%E6%B5%B7%E6%8A%A5.txt

        P1496火烧赤壁.txt · 王子萌/练习代码 - Gitee.com 

11、递归初阶 

        现在的递归我们应该从宏观角度去看。而不是像刚接触递归时一点点把递归拆开来看。递归的写法还是比较固定的。

        第一,设置出口。档出现什么什么条件时,返回。但需要注意的是递归出口不一定只有一个。

        第二,处理当下这一步。我们只需要把眼光放到这一步,下一步我们不用管他具体怎么做的,只需要调用一下递归函数就可以了。

        P10457 占卜DIY.txt · 王子萌/练习代码 - Gitee.com

        https://gitee.com/ZiMeng-Wang/practice-code/blob/master/P1087%20[NOIP%202004%20%E6%99%AE%E5%8F%8A%E7%BB%84]%20FBI%20%E6%A0%91.txt

         

12、分治

        分治分治,分而治之。

        我们之前接触过的归并排序,就是分治思想。遇到一个问题,我们首先把这个问题拆解成一个一个的小区间,然后再对于每个小区间,我们去操作,最后在合并到一起。分治和递归一样,我们不需要去考虑它的细节 考虑他具体是怎么怎么操作的,我们只需要管好当下这一步就可以了。

        P1908 逆序对.txt · 王子萌/练习代码 - Gitee.com

        P1923 【深基9.例4】求第 k 小的数.txt · 王子萌/练习代码 - Gitee.com

        P1115 最大子段和 分治.txt · 王子萌/练习代码 - Gitee.com

        好了,今天的内容就分享到这,我们下期再见!

相关文章:

  • 【JAVA架构师成长之路】【JVM实战】第1集:生产环境CPU飙高排查实战
  • DeepSeek本地调用,集成到自己的平台中,做二次集成
  • 2025-03-06 学习记录--C/C++-C 库函数 - strcat()、strncpy()
  • 【每日学点HarmonyOS Next知识】Web上传文件、监听上下左右区域连续点击、折叠悬停、字符串相关、播放沙盒视频
  • 微服务架构下的 Node.js
  • [项目]基于FreeRTOS的STM32四轴飞行器: 四.LED控制
  • vue基本功
  • Devart dbForge Studio for MySQL Enterprise 9.0.338高效数据库管理工具
  • 在线SQL转ArkTs
  • PTA 7-6 列出连通集
  • Terraform 中安全地更改 EC2 实例 instance_type 的指南
  • idea 复制代码时不带富文本背景色
  • 记录一个Circle CI出现的错误
  • 全员DeepSeek时代,前端能做些什么?
  • 捣鼓180天,我写了一个相册小程序
  • 快速从C过度C++(二):引用,内联函数,nullptr
  • 通过u-boot启动Linux时的根文件系统挂载流程(init进程可能会进行二次挂载)
  • 前端实现版本更新自动检测✅
  • Redis渐进式遍历数据库
  • Mybatis中的分页操作,如何使用PageHelper进行分页,以及Spring Boot整合Mybatis Plus分页
  • 做商城网站在哪里注册营业执照/凡科建站怎么用
  • 网络美工是做什么的/seo怎么做最佳
  • 外贸做消防的网站/自动连点器
  • 网站项目书范文/怎么做市场营销和推广
  • 公司网站建设开源平台/电商运营工作内容
  • 网站域名打不开的原因/营销活动方案模板