- 博客(96)
- 收藏
- 关注
原创 Monoxer Programming Contest 2024(AtCoder Beginner Contest 345)题解
我们从叶子节点开始一层一层往上的话,开的灯会多一些,因为如果先开了父节点,那么开叶子节点的时候,父节点的状态就是不确定的了,但如果先开了子节点,那么用父节点的父节点去开的时候就不会影响子节点。显然是可以的,不过要注意,我们需要考虑结尾的颜色,所以最大值不一定能用,故而应该同时维护一个次大值,一定要保证最大值和次大值的颜色不同,将这两个值和两种颜色记一下,然后不断遍历,不断更新即可。有n个灯泡和m条边,每条边连接两个灯,我们任意选边,然后将边上开着的灯关掉,关着的灯打开,问最后能否恰好有k个灯打开。
2024-03-19 07:54:48
1093
原创 Educational Codeforces Round 163 (Rated for Div. 2)题解
显然,如果它向右移,然后右边的格子的字符是向左,那不管它怎么向右移动都是无效的。往左操作就真的是无效的了。思路:这题说前半段等于后半段,我还以为是kmp,但比赛那会儿时间太紧了,没写出来,比赛结束后才发现我高看它了,根本就用不着kmp,我们只要枚举子串一半的长度,对于每个长度从s的第一个字符开始找,s[i]=s[i+k]就将计数的变量+1,否则就将计数的变量置为0,一旦计数的变量等于k,那么就说明对于这个长度我们找到了一个合法的子串,这样一直往后枚举,最后就能得到最长的长度。问这样的子串最长有多长。
2024-03-17 10:20:14
688
原创 平衡树——treap
一种是要删除的数在叶子节点上,那么我们直接把这个叶子节点的下标修改成0即可,因为我们在上一层传入的是它父节点的tr[u].l或者tr[u].r的引用,所以这里直接赋成0就相当于将它父节点的左指针或者右指针的指向修改成空;通过前三个赋值,我们已经实现了子节点的交换,相对于原来的p的父节点的更新我们该怎么实现了,显然我们没有存父节点的信息, 不能从子节点访问到父节点,但是我们肯定是在递归中实现的,我们只要在递归的时候传入tr[u].l的引用,那么在这一层进行修改的时候就可以实现对tr[u].l的修改。
2024-03-16 13:11:02
1475
原创 操作系统——进程
概念: 进程是一个具有一定独立功能的程序关于某个数据集合的一次运行活动,是系统进行资源分配和调度的一个独立单位。进程是程序的依次执行进程是一个程序及其数据在处理机上顺序执行时所发生的活动进程是程序在一个数据集合上运行的过程进程是系统进行资源分配和调度的一个独立单位结构:控制块(PCB):进程的唯一标识,每个进程都不同,即使相同的软件的不同执行次数PCB 也不同数据段:存放原始数据、中间数据。
2024-03-14 17:57:58
1323
原创 c++面向对象
公有:类的外部(主函数里或者其他类)可以读写name的值私有:类的外部外面看不到可以只有public,没有private的类相当于结构体类被定义后,创建类的对象形式和int a一样;给类中的属性赋值和结构体一样。
2024-03-14 14:26:20
860
原创 Codeforces Round 931 (Div. 2)题解
思路:这里的操作是异或,所以我们从二进制的角度来考虑,显然只有两者二进制位不同的时候才需要改变,每一位上如果需要变,要么是0变1,要么是1变0,对于0变1,n实际上会变大,所以我们要找一个更高位1变0来和它同步变化,否则n^x>n,就不满足要求。所以我们可以先遍历它们二进制的每一位,然后标记一下每一位,如果是1变0,标记成1,如果是0变1标记成2,然后从小往大遍历,每次当一个标记为2的位需要改变的时候,我们就往前找到一个标记为1的位和它一起变,否则如果找不到就直接退出输出-1,如此便可解决。
2024-03-14 09:06:58
790
原创 Codeforces Round 933 (Div. 3)
这题实际上还可以用双指针来写,我们将b[]和c[]都排序,然后用一个指针从小开始扫描b[],另一个指针从大往小扫描c,对于b[i],我们找到了一个合适的位置c[j],那么i往后,则b[i]变大,那么c[j]就应该变小,所以两个指针之间都是单向的,所以可以用双指针来写。但是有一点要注意,首尾必须选,这个还是有点麻烦的,但是也还好,我们最开始的队列为空,那么第一个元素被放进去后,后面的元素都会用它来更新,保证末尾元素被选,那么我们直接取dp[m]即可,因为集合定义的时候就是dp[i]中i一定被选。
2024-03-13 10:19:40
1181
原创 ACDC-2024-10
我们需要统计出这个区间的一些属性,区间长度和最大值,对于这两个值我们可以维护循环外的变量来表示。因为维护区间的值是循环外的变量,所以我们访问下一个数的时候需要将当前树的相关属性刨掉,但是可能当前树根本不能被选,那么就相当于当前树是新开的,否则是可以被选的,如果当前树是新开的,且不可以被选的话,此时,cnt和sum刨掉当前树后都变成赋值,我们可以把它们设为0,同时如果cnt为0,那么就证明下一个树需要新开区间,不能从前面继承区间,所以我们将last的值修改成下一个位置的值,保证while循环可以正确运行。
2024-03-13 00:16:02
747
原创 Codeforces Round 932 (Div. 2)
如果弹出的是中间的值,那么就无所谓,反正本来所选的部分就不用连续,但是如果弹出了左右边界,那么我们维护的br-bl岂不是失效了,假设我们真的弹出了左右边界,那么当前的左边界应该是l+c,右边界应该是r-d,这个区间我们在设定左边界为l+c的时候会遍历到,而且因为区间缩小了,左右边界更近了,所以实际的br-bl可能会变小,这里用一个更大的值来表示,不会多算,但是却可以帮我们访问所有的情况。我们是可以枚举集合中的每个数的,那么能否通过枚举集合中的数,将不符合要求的点对的数量统计出来呢?求差成立的话有多少对呢?
2024-03-09 10:01:02
1129
1
原创 可持久化数据结构
可持久化数据结构必须满足在操作过程中数据结构本身的拓扑结构不变,可以用来存下数据结构的所有历史版本。核心思想:只记录每一个版本与前一个版本不一样的地方。这里我们讨论两种数据结构的可持久化——trie和线段树。
2024-03-05 20:49:50
889
原创 线段树模型及例题整理
还是先来看如何定义结构体,显然我们需要储存最大连续子段和,但是这样够不够呢,显然是不够的,因为子节点无法更新父节点,虽然父区间的最大值有可能是左右子区间中的一段,但是还有可能是跨区间的,如果是跨区间的话,要想更新就需要用到左区间的最大后缀和右区间的最大前缀,那么现在就要多维护两个变量——最长前缀和最长后缀,那么现在考虑最长前缀和最长后缀能否能通过子节点来更新父节点,显然是不可以,以最长前缀为例,要用子节点计算的话,有两种情况,一种就是左子节点的最长前缀,一种是左区间加右区间的最大前缀。
2024-03-02 21:39:32
759
原创 Codeforces Round 930 (Div. 2)题解
我们还是想办法从这道题的特殊的地方入手,题目中给的数组是一个排列,从0到n-1的排列,那么最大的数显然是n-1,然后要找出n-1为0的哪些位置为1的数,显然两者进行|运算的值应该最大,但是如果仅仅是找或运算的话,那么n-1为1的位置,且找到的数对应位置也为1的位置的那种值如何排除呢,显然我们的目标值中1的个数最少,目标值为1的位置所有找到的值对应的位置应该也是1,但是应该比目标值大。(1<=n<=5e5)获取n的第i位是否是1,判断n>>i&1是否为1,如果为1,就说明n的第i位为1,否则就是0.
2024-03-01 21:02:09
1052
原创 Codeforces Round 929 (Div. 3)题解
但是可能因为太着急了,并没有仔细分析性质,一直改一直交一直wa,最后终于想着分析一下,这一分析就找到问题的关键了,对于这个二次函数,很显然最大值应该在u+1/2的时候取到,但是因为值都是整数,所以要么在u处取到最大值,要么在u+1处取到最大值,所以我们可以找最接近u的数,那么我们可以通过找到第一个大于u的值来实现,因为跑道长度都是正的,所以一定是单增的,可以用二分来查找。思路:这题有个很巧妙的地方,最多操作两次,因为原数组的和mod 3只有三种情况,0,1,2,如果是0,那么就不用操作;
2024-02-29 13:43:27
997
原创 树状数组模型及例题整理
那么我们该如何统计呢,如果一个位置上的数出现,那么我们可以对它进行标记,即让a[]数组的这一位为1,进而去更新tr[]数组,那么查询的时候查询sum(y),则查询到在1-y中有多少个标记,也就是小于等于y的数有多少个,我们再查询一下sum(n),n是最大的数,这里查询出来的结果就是在1-n之间有多少个标记,那么就是小于等于n的数有多少个,也即当前已经插入多少个数了,两者相减就可以得到当前有多少个大于y的数,因为我们是按顺序插入,所以i左边大于y的数的个数我们就统计出来了。
2024-02-26 21:32:19
787
原创 并查集及应用
那么如何判断是否产生矛盾,我们可以通过两者与根节点的距离来判断,因为只有奇偶两种情况,我们可以定义只有两种距离0,1,如果奇偶性相同,那么两者之间这一段就为偶,如果奇偶性不同,那么中间这段就为奇。两人轮流画,谁先封圈谁赢,这里可以用边的双连通分量来判断(因为连的是无向边,但是很显然加一条边tarjan一次太麻烦了,这里可以先记录所有的边,然后二分判断是否封圈,但是这题有更简单的方法)这里从并查集的角度来考虑的话,封圈就意味着,两点之前应该就属于一个集合。1252. 搭配购买(还有一种做法——扩展域。
2024-02-26 13:35:02
934
原创 欧拉回路和欧拉路径
但是这里如果仅仅通过h[u]=ne[i]来删除,后面遍历时可以生效,但是回溯到前面遍历并不是再从开头开始,所以并没有生效(或者换个角度来理解,我们的删除相当于直接将头节点的指针往后移,但是中间节点的指针是没有改变的,所以实际上前面的循环应该已经到了中间那么节点的部分,它们之间的指向关系并没有改变,仍然会产生新的递归循环)时间复杂度还是很高,那么该如何处理呢,我们这里通过传入指针来实现动态的删除。所以可以见得,判断欧拉回路和欧拉路径,只要判断度和连通性的性质满足即可,方法不唯一。1124. 骑马修栅栏(
2024-02-22 21:07:45
684
2
原创 拓扑排序模型及例题整理
这里有个条件,如果在x停靠,那么所有等级大于等于x的都要停靠,所以我们对于每一趟车统计哪些站停靠,哪些站没停靠,最好的情况就是假定所有停靠的点等级都相同,且比未停靠的点大1,那么就可以用差分约束那里的建边方式来建边,但是由此来看的话,需要建的边实在太多了,我们可以引入虚拟点,即在对于每一趟车假定一个虚拟点,从未停靠的车站到虚拟点建一条长为0的边,从虚拟点到停靠车站建一条长度是1的边。统计的时候稍有不同,因为我们不能只是数值上的累加,这样的话就会有点被重复计算,我们需要确切的直到当前点可以到哪些点。
2024-02-22 20:57:12
611
原创 二分图模型即状态整理
思路:首先我们注意到,需要将所有罪犯分到两个监狱中去,那么联想到二分图,二分图的要求就是边全部在两个集合之间,集合内部没有边,但是这里显然不能保证图是符合要求的,但是我们要求的是最大值最小,所以考虑二分,对于一个二分值,如果小于等于这个二分值的可以分进一个监狱,否则就必须分进两个监狱,那么从二分图的角度来看,相当于只保留了大于二分值的边。对于一个点,它能攻击到的点与它的横纵左边之间的总差值应该是一个奇数,那么就会改变奇偶性,那么我们按照奇点偶点分成两个集合,那么就是一个二分图。得到的路径是一个增广路径。
2024-02-21 19:19:33
849
原创 无向图的双连通分量
思路: 本题要求删除一个点之后还剩多少连通块,首先在连通块内部删除一个点,对其他的连通块是不产生影响的,那么就需要考虑删除这个后在连通块内部产生多少个新的部分,首先如果这个点不是割点,而是属于一个连通分量中,那么删除之后也不会产生任何影响,所以只有割点被删除才会产生影响,所以问题的核心就是找割点,那么就可以直接用tarjan算法了,不过还有一点比较麻烦的在于还需要判断这个点是否是根节点,如果不是根节点,那么删除后除了子树还需要多一个连通块。点连通分量不一定是边连通分量,边连通分量不一定是点连通分量。
2024-02-21 15:57:24
666
原创 有向图的强连通分量
我们建边的时候就跟糖果那道题一样建边,如果a>=b,那么就建一条b指向a,长度为0的边,如果a>b,那么就建一条b指向a,长度为1的边,然后计算强连通分量,再缩点成有向图,起点的亮度是1,递推求总和。另外,一个强连通分量的各个点亮度应该是相同的,所以所有的边权都应该是0,否则就不成立,输出-1,我们在缩点的时候记录一下。那么p2和q1就变成中间节点了,可以从起点和终点的集合中去掉,那么大小同时减1,然后可以去p-1次,变成p==1的情况,那么还需要加q-(p-1)条边,那么总共就加了q条边。
2024-02-20 16:48:02
1259
原创 最近公共祖先(LCA)
先kluskal求出最小生成树,然后根据最小生成树建一张无向图,然后用倍增法写lca,在lca预处理的时候,将d1[i][k]、d2[i][k](i上跳2^k的过程中的所经过的边的最大值和次大值)预处理出来,对所有的非树边执行lca查询,在lca查询的时候,将两个到最近公共祖先的过程中经过的所有最大值和次大值存下来,然后找出总的最大和次大,进行计算,返回结果。这里我们对于一条非树边,它们的最短路径上所有的边的值都要加1,这里可以利用差分实现,即,两点的d各加1,lca的d减2.1.遍历过还没有回溯过的点。
2024-02-20 11:50:52
1026
原创 最小生成树算法及例题整理
本题看似麻烦,但是既然涉及到最小生成树,那么我们可以想一想最小生成树的建立过程,我们从kluskal的角度来考虑,每次建边,就是将两个 不连通的集合连通,两个不连通的集合就说明除了当前这条边以外,两个集合没有任何边相连,如果要得到完全图,那么很显然两个集合之间要建立更多的边,这些边的具体数目取决于两个集合的大小。这个算法的思路就是将所有的边排序,然后从小到大遍历所有的边,如果这条边连接的两点不在一个集合中,那么就将它们并成一个集合,否则就略过这条边。最开始连通块的数量肯定是n,每连接一次,那么数量就少1.
2024-02-19 10:54:47
1948
原创 最短路相关模型及应用整理
这里我们开始分析最短路问题,我们先来看最基础的最短路算法:下面我们分析下每种算法的思路,并不展开论述例题,例题的分析求解放在最后的链接里。
2024-02-17 23:34:24
690
原创 Floyd算法例题整理
这题还有一个难点在于需要将环输出,这个其实可以由最短路的特性得到,我们来想一下,虽然是分了n类来看,但是我们实际上只要维护一个变量来存最小值即可,最小值每次更新的时候,就说明有一个环了,我们可以用一个数组来存这个环,显然环上有i,j,k三点,那么问题就转化成中间的那些路径该怎么求,中间的那些是如何得到的呢,显然是在更新d[i][j]的时候得到的,那么我们只需要记录一下d[i][j]是被哪个中间点更新的即可还原路径(用递归实现)。思路:题目的意思很清楚,需要求一个环,环的要求是边的长度之和最小。
2024-02-17 23:32:45
1327
原创 单源最短路的扩展应用
首先要解决的第一个问题就是这里的我们只给出了有门和有墙的状态,剩下的那些可以直接到的点之间的关系需要我们手动来建,这里建边的时候,门位置可以在输入的时候就建边,墙位置不能建边,所以要判断两点之间是否是墙,可以将所有的墙都记录下来,直接连通的位置也是要建边的,但是需要与门区别,我们将边权定义为0.思路:这里要求的是最短路的条数,我们联想到dp中的方案数来解决这道题。还有,这道题求的是时间花费,只有移动是花时间的,所以我们拾钥匙的操作花费的时间是0,移动花费的时间是1,所以我们实际上可以通过双端bfs来实现。
2024-02-15 18:07:13
648
原创 单源最短路的综合应用例题整理
这里有五个点需要被遍历到,要求遍历完五个点总路程的最小值,那么首先的问题就是确定这五个点的遍历顺序,显然我们需要dfs一下,然后我们还需要知道任意两点之间距离的最小值,很容易想到floyd算法,但是这道题n的范围有些大,并不支持floyd算法,但我们注意到我们只用知道这6个点之间的关系就可,那么我们可以在每个点的位置做一次单源最短路,这样的话时间复杂度是支持的。然后还有一个问题,可能会质疑最大值出现在最小值前面的情况,但是我们并不是将第一次出队时的值就视为答案,如果是双向边,那么前面的也可以更新后面的。
2024-02-15 13:51:39
868
原创 单源最短路建图方式例题整理
然后我们就时间复杂度进行分析,朴素版dijkstra算法的时间复杂度是O(n^2),本题的点数是2500,n^2=6250000,数量级1e6,可以过;虽然这里是最大,但是我们存边可以存成实际的百分数,那么就会越乘越小,所以当一个位置第一被作为最大的挑出来的时候,就是此处最大的位置。然后去搜到终点的最短路。然后就是考虑时间复杂度的问题,朴素版O(n^2)=1e4,堆优化O(mlogn)=400,spfa一般O(m)=200 最坏O(nm)=2e4,所以三种算法都可以,这里还是本着复习的想法全部写一遍。
2024-02-14 20:51:24
1039
原创 Codeforces Round 886 (Div. 4)补题
这里还有一点要注意,因为我们为了避免dfs时死循环,会对访问过的点进行标记,但是如果我们只建立单向的边,就会在5->4的时候出错,因为dfs(4)的时候已经将4标记过了,所以在访问5的时候会直接将4跳过,那么它们之间的关系就不会被表示出来,但是如果我们建立双向边就不会出现这个问题了,另外还有一点要注意,边权是很大的,所以有爆int的可能,我们需要用long long来处理。题目大意:现有一个指南针,只能指向八个方向,现在坐标轴上有一些点,我们将指南针放在一个点上,如果它能指向另一个点的话,它就不会坏。
2024-02-10 19:17:43
1052
原创 Codeforces Round 887 (Div. 2)补题
然后来看下一位3,很显然,这里有一个大于0是加上前一个数得到的,那么这一位和自己以及后面的数加起来应该只有2个大于0的数,这两个数出自哪里实在不好确定,那么我们换个角度去看1,对于1来说,很显然它仅仅与第一个数的和是正的,那么我们就将它赋为-3,再往前推,9在第4位,上次删除了1,3,所以9往后推两位,9在第6位,删除了第5位,所以再往前推9在第7位,删除了6,再往前推,9在第8位,删除了7,再推,9在第9位。然后再来看2,很显然这里的2是和前面两个数,那么它与自己的和是负的,那么显然可以直接赋成-1.
2024-02-08 20:47:20
889
原创 DFS——迭代加深、双向DFS、IDA*
迭代加深主要用于dfs搜索过程中,某条支路特别深,但是答案在特别浅的地方,也即在另一个分支中,但是按照dfs的原理,我们是将这条支路搜完才去搜另一条支路。所以我们就要及时剪枝,而迭代加深算法则是指定搜索层数,一旦某个分支搜索的上限达到这个搜索层数了,那么我们就直接剪枝,不再往后搜了。如果当前指定的层数不能搜到结果,那么我们将指定层数再扩大一点。这里就会有疑问,如果答案在第10层,那么0-9层都是冗余搜索,但是实际上,0-9层的搜索规模相对于第10层来说微不足道,主要的复杂度还是以第10层为主。
2024-02-08 18:34:05
1170
原创 Codeforces Round 923 (Div. 3)补题
显然非桥边可以连接两个集合,所以我们只需要将所有边按照边权从大到小排序,然后依次判断每条边是否能够连通两个不同的并查集,如果可以的话,那么就是桥,如果不可以那么我们就可以记录它,因为它是非桥边,因为我们按照边权从大到小排序,所以最后一个被记录的非桥边就是我们要找的边。另外我们在建边的时候,因为最开始一条边都没有,所以有一些非桥边会被当成桥边,但是由于我们是从大到小访问的所有边,所以每个简单循环中的最轻的那条边一定会被记录下来,因为这条边一定是这个循环中最后被加入的边,它的两个端点一定属于同一个集合。
2024-02-08 13:58:51
847
原创 DFS——剪枝
这里我们可以用一个二进制数来表示每行每列每个3*3的方格中的状态,比如,对于第i行,我们用row[i]表示一个二进制数,这个二进制数中如果某一位上是1,那么就说明这一位对应的数可以填进这一行,那么对于一个空格,我们只要将它的行列以及一个3*3的方格中的状态求&,那么就可以获得这个位置可以填哪些数,求&之后的结果是一个二进制数,所以我们要想得到每一位具体填什么还需要再处理一下。1.优化搜索顺序,对应到这道题就是先搜重的猫还是先搜轻的猫,显然先搜重的猫比较好,因为重的猫可以占掉更多的空间,让后面的情况少一些。
2024-02-07 22:16:25
1740
原创 Codeforces Round 888 (Div. 3)补题
所以可以用map将所有的出现的数及它的出现次数统计出来,然后遍历map,将小于等于n的数标记一下,同时在map中减掉一次,然后遍历n,找一找有几个数没被标记,同时计算出没被标记的数的和,如果是一个,那么直接输出yes,如果是两个,那么就看两个数的和是否在map中,如果大于两个,直接判否。一定要把题目看清楚。思路:这题没什么难度,就是小f与其他人的高度差要恰好是k的倍数,同时有两个限定条件,两人不能站在同一级台阶上,则不能与高度相同的人进行交谈,另外台阶总共m级,到第m级时就到终点了,所以倍数需要小于m。
2024-02-05 20:48:44
725
原创 DFS——连通性和搜索顺序
有内部搜索和外部搜索两种,内部搜索是在图的内部,内部搜索一般基于连通性,从一个点转移到另一个点,或者判断是否连通之类的问题,只需要标记避免重复访问即可,不需要还原状态,而外部搜索则是将一张图视为一种状态,每一个状态延伸得到新的状态,要保证每个状态往外延伸时都是相同的,那么就需要还原状态。思路:如果我们将第一个数放在第一组,那么遍历后面的数,如果不与第一组中的数互质,那么就可以放进这一组,否则就只能新开一组,如此递归来实现,就可保证将所有的数都分好组,同时是分组最少的。1116. 马走日(
2024-02-04 23:01:35
654
原创 BFS——双向广搜+A—star
可以这么来理解,如果我们在行内进行移动,实际上并没有改变序列,也就是并未改变逆序对数量,如果在行与行之间进行移动,那么相当于只改变了它前面或者后面两个数的位置,我们以一种情况为例,它实际上就只改变了3个数内部的相对顺序,所以实际上逆序对的数量要么不变要么就多2或者少2,所以起始状态和结束状态中逆序对的奇偶性相同,我们可以顺序排列的时候逆序对的数量是0,那么起始状态中逆序对的数量应该是偶数。有时候从一个点能扩展出来的情况很多,这样几层之后搜索空间就很大了,我们采用从两端同时进行搜索的策略,压缩搜索空间。
2024-02-04 18:28:27
1185
原创 Codeforces Round 891 (Div. 3)补题
思路:很显然,我们在选的时候如果当前位是大于5的数,后面有能让它变成6的数,它变了对前一位的贡献也还是1,所以没什么区别,如果是9的话,进位变成0,前一位加1,和直接从这一位进位区别不大,所以我们只需要找到第一个可以进位的地方操作一下即可,对了,记得往前累计,另外边界值的处理什么的也要注意一下,不然没注意越界的话会有特殊字符输出,但是本地编译器可能看不到。思路:很显然只有奇数+偶数=奇数,很显然偶数可以随便分,那么我们只需要统计奇数的个数,如果奇数的个数可以平均分进两堆,那么奇偶性就相同,否则就不同。
2024-02-04 13:16:30
706
原创 Educational Codeforces Round 153 (Rated for Div. 2)补题
思路:很容易发现,我们相当于是找以某个点结尾的单增序列的最长长度,如果长度等于2,那么很显然,B移动一次,轮到A,那么A此时不能移动,胜利,如果等于长度等于1,显然B直接胜利,如果长度大于2,那么B可以将芯片移动到倒数第二个位置,A移动一次,然后B胜利,所以只有长度为2的时候,是幸运位置,但是有一点比较麻烦的是,这题的数据范围是t是1e4,n是3e5,那么需要用线性的时间复杂度来解决。check函数检查凑出m需要补多少个硬币,肯定优先补价值k的花式硬币,如果差值小于k之后再补价值为1的花式硬币,
2024-02-03 13:56:05
429
原创 BFS——多源BFS+双端队列BFS
另外我们再来看看这里要求的量,一个是求最小的操作次数,另一个是求字典序最小的操作序列,这里为了得到字典序最小的操作序列,实际上我们按照ABC的顺序来更新,再将更新到的序列放入队列即可。按照这个图就很明显,每个点只有四个点是可以到的,那么我们就来思考一下如果这四个方格中的线的路径与给定的相同,那么显然就不用操作,否则就要进行一次操作,所以我们到下一个点的边权可能是1,也可能是0,为了保证队列的单调性就不能直接放队尾,那么我们可以直接令为0的时候从队头插入,为1的时候从队尾插入,那么可以用双端队列实现。
2024-02-02 20:42:53
400
原创 BFS的基本应用——flood fill && 最短路
bfs的核心就是一层一层往外扩展,在bfs中会用到一个队列,又由于是一层一层往外扩展的,故而可以用来求连通的问题,同时相当于每次往外扩展的边权都是1,所以这个队列是有序的,相当于dijkstra算法中的优先队列,那么也可以用来求边权为1的最短路问题。
2024-02-01 20:23:15
978
空空如也
TA创建的收藏夹 TA关注的收藏夹
TA关注的人