CF——错题的集合

CF1902C Insert and Equalize

这题lz一开始看到要构造两个数,再加上找不到啥规律,一开始是朝着所有数的和思考,因为我把插入的数看作是每个数的目标,但是我忽略了x,所以我没想出来。因为这题的关键是找到x,找到插入的数要排在找到x的后面,因为插入的数其实是通过x得到的。我还有一个错误的原因就是将目标数与所有数的和找关系,其实是数组里的最大数。

这个最大的数是怎么得出来的?,可以这么说,因为每个数都要加上x再加上每个数都不同,故想到以最大的数作为目标数。但是为什么不用数组中的最大数加上x作为目标数以及插入的数?这很好想,因为这么做,前面的数,本来到了原数组最大数步数就停止增加了,但是如果用插入的数,那么又要再往前多迈几步,不符合贪心的策略,那么我们就要从比最大数小的数里选,同时要满足不与数组其他数字重复,所以我们可以选比最大数小几个x的数(更详细的方法放在代码分析里)。问了两个问题,其实结果的依据都是在分析出x的基础上。

所以我们现在就来分析。我们设T为目标数,那么第i个数从ai到T通过加上ki个x的过程可以表示为T-ai=ki*x,如果有任意两个这样的位置相减,可以得到ai-aj=(ki-kj)*x,那么也就是说任意两个位置之差都要被x整除,那么我们就可以以此来求出x(g=gcd(g,ai-ai-1,代码部分,也是我一开始不理解的部分)。那么代码我们就可以这么写,先写出排序数组找到最大值,然后根据上述步骤,求出x,然后我们就可以根据每个数与T差了多少个x来计算总步数,同时我们可以定一个排列(set<int>)来存每个数的每个步数,这样的作用就是通过这个队列来从1开始找到那个插入的数,(因为这个插入的数可以用与T差了多少步来替换)(while(s.count(mex))mex++)(这个s就是这个排列的名称,这个mex就是我们所插入的步数。最后将这些步数加入ans输出即可。

CF1889A Qingshan Loves Strings 2

这道题lz一开始并没有什么特别好的思路,再加上模拟我不太想用,所以就看了题解,现在看代码还有思路都有些东西值得讨论的。

首先有两个结论可以直接排除永远不可能的,首先就是n等于奇数的时候,插入01,也就是说每次会给数组长度增加2(需要注意),也就说不管加多少个01,数组的奇偶性都不会改变,当其为奇数,前后两两对应,最后会剩下一个独狼,然后这个狼会和自己比,而它永远等于它自己,也就是永远不符合条件。

然后就是当数组中0的个数不等于1的个数是,同样从插入01入手,每次插入,数组中的01数量之差不会改变,也就是说一开始不同就会一直不同。那为什么会不满足。为了满足不是回文数,我们必须让每个0与1对应,这样才不会出现相同的情况,那么当一开始数量不同时,它必然无法变成好数组。

代码部分有一个点容易忽视,就是我们每次对数组进行插入之后要改变数组的长度也就是+=2。然后,我们就可以用ans存储答案,遍历到数组的一半,如果等于这个位置不同就跳过,如果相同,1的话在前面插入(i),0的话在后面插入(n-i)(插入用insert),然后存储每次插入的位置。最后循环输出ans即可。

CF2257C Spying on the Beaver

题读不懂的感觉,没想到有中文我都读不懂,没想到1尽然是根,感觉我读不懂跟翻译也有关系(为啥不直接告诉我1是根)。

但是这个树我的感觉不太好,可能是做少了吧。说到底还是没完全理解这道题。题目要我做的是找到几条边放上照相机,就是记录海狸是否到过,通过相机判断它要到哪个大坝。不知道咋办,我可以从两个大坝开始考虑,假如大坝在上下关系,那么要在这两个大坝之间就好例如1-2-3,(3的父亲是2,1是根)大坝在23的时候,2的情况可以标记为\[\],3的情况可以标记为2,3,这样我就可以区分2、3,也就是说我可以通过安排相机的位置来让每个大坝具有自己的"指纹"(这个比喻来自ai)。然后带着这样的思路,我们来考虑三个的情况,假如这三个大坝在两个分支里,右边分支一个大坝,左边分支两个大坝,那么我要怎么安排,最简单的情况就是每个大坝都安排一个,但是要满足题目里的最少相机。那先满足它,不放不行的话就先放一个,发现不管放哪里,无法区分三个大坝。那么就试试两个,我们可以放在左边分支入口,以及左边分支中的一个大坝

CF1882B Sets and Union

我一开始是有点感觉的,但是我觉得直接模拟不太好,没想到答案就是直接模拟,不过思路上还是有一些地方值得探讨。我被题目要求找到S的最大长度,要求S不能等于所有小数组的并集,并且,S要等与一些小数组的并集。研究了样例,我发现,我们可以从删去的角度思考,要使得S长度最大,要让删的最少,我开始以为要找到每个数出现的次数,如果又出现1次的,就直接输出总长度(数的所有种类)-1,但是样例中n=5的那个打了我的脸,我们删掉的是出现次数为2的1,出现次数为1的一个都没删。

后来我就去问ai了,既然知道了要删除某个数,为什么不一个个模拟。思路是这样的,找到所有数的总和,每个数都删一遍,删掉它意味着,不会取包含它的小数组,这说明我们也要将每个小数组存下来。

代码的话,我们可以通过set存所有数以及小数组的(set<int>,vector<set<int>>),然后遍历all(所有数组的并集),再遍历每个小数组,找到不包含当前数的数组,将里面的数存起来,遍历完所有的小数组后,将ans赋值为max(ans,(int)cur.size())(cur代表的就是不包含那个数的所有小数组的并集)(为什么要用int)。遍历完all,输出即可。(注意:定义小数组变量的时候,要写上s(n),因为后面要用到si)。

CF2187A Restricted Sorting

这题我开始以为只要不符合递增的前后两个数交换之后取差值然后求这些值的最大值即可。但是这样肯定是错的,用一个样例反驳4,3,2,1。还有一个错误的原因,就是每次交换最近的两个数,我的代码就会退出循环,因此,样例经过我的代码就变成了:3,2,1,4,输出3,因为4、1交换的是数组中最大的。首先我没有将他变为彻底的递增,这点错误;其次就算答案是3,但是知识凑巧罢了。

真正的思路应该是先排序,然后找到这个位置ai!=bi的(a表示排序之前的数组,b表示之后的),这个位置说明是要交换的,这种方法就不会出现我上面的未完全升序的情况。然后我们要对它进行操作得出k,k的定义是这个交换两个数的差值要大于等于k(漏了一个结论,放在最后说),我们直接判断最坏的情况,ai要和b的两端交换,也就是数组中的最大最小值,那么k要满足的条件就变成了<max(ai-mn,mx-ai)(这里的mn为最小值,mx最大值),为什么?因为这里是活着的关系,也就是说ai-mn>=k,mx-ai>=k只需要满足其一,所以为了让k尽可能地大,我们选择满足较大的那一个。最后就是ans要取所有k中最小的那一个,这个就是为了满足题目的要求了,因为一个小猪数组只能有一个k。

最后是那个漏掉的结论,数组只要交换就可以排序,只不过是间接或直接的关系。这题关键的点在于k要满足的那两个值得较大的那一个。

CF2173C Kanade's Perfect Multiples

lz废了,我想的是找到a中质数的倍数在a中有没有不存在的,如果有,那么肯定输出-1,因为没法满足条件2,这个理论要用到一个前提,就是a最小的一定在b中。我大概就是没有得出这个结论导致没有很好起步思路。

让我们来论证这个结论,假如放入b中的数不是最小数,那么为了满足条件1,那么一定会有一个更小的数被放入(和我的质数有点像,不过最小数会比我的质数更好理解和简单)。

代码的思路就是用两个列表存A数组,一个用来判断,就是当指针指向这个数,找到这个数所有倍数(乘以1,乘以2,乘以3......)然后跟另一个列表比较,如果这个列表里没有,那么就输出-1,如果有,那就在第一个列表删掉它(因为最小数的倍数不用存入B)

CF2157C Meximum Array 2

min和mex就不介绍了,老朋友了。一开始的时候我被正确性判断卡了好久,因为题目并没有明确指出给出的答案一定行。想通之后就变得非常简单了。

这题得核心是我们要明白为什么这么构造是对的。先说构造思路,被c=1染色的区域,都令它为k,而被c=2染色的区域,循环构造0~k-1(用到了mex的理论),要明白为什么,我想必须明确知道,这题是一定有答案的才行。然后这题思路就结束了。(不告诉我一定能够成立虽然搞人,但是这应该是这题的难点)

代码部分,两个动态bool数组来存c=1,2的状态。然后创建一个动态数组来存答案。然后遍历1~n,先判断是否同时具有两种状态(这里补充一下,思路分析没说到,就是这个位置两种状态都具备,为了满足,它既不能小于k,也不能不是0~k-1,那就令其为k+1,别的也行只要大于k)(搞清楚了我前面补充的,基本上就都搞懂了)。假如这个位置同时具备两种状态,我们定为k+1。假如只有状态1(c=1),那就定为k。假如只有状态2(c=2),那就循环定为0~k-1(该怎么实现,cnt%k,然后cnt++,这里可以思考一下)。假如都没有(all false),那就随便(定为k+1)。最后循环输出即可。

CF2259E Treasure Map Destruction (Constructive Version)

一开始lz卡在了可行性判断上,我的结论被样例中的最后一个反驳了。我想的是直接找到大于等于0的数,然后再特判行不行,当时漏了如果有一个更近的藏宝,那我就得遍历这个区域(假如题目给的数组中第i个位x,那么这个区域就是 i-x,i+x。时间复杂度直接O(n方)。是过不了的,然后我就没招了。

直接说代码思路,感觉题目的思路在说完代码也差不多了。代码里要用到的是差分加前缀和。这两点也可以说是我最大的收获了。那么他们有什么用呢?题目中我们直接去找到这个数的两个端点不太行,已经证明过了,那么可以将这个数字看成限制条件,就是在这个区域内(不包含端点)不能有宝藏。而我们的差分和前缀和正好可以实现这一点。首先先差分(定义一个数组diff来存差分结果)(diff初始值都等于0),找到原数组中大于0的数(-1和0直接跳过)然后令diffmax(i-x+1,0)++,然后有端点--,这里注意右端点不需要-1,原因的话我应该会放在前缀和,并且与n比较而不是n-1(这里我的意思是数组是从下标0开始赋值的)。右边的在diff中值要--。

然后进行前缀和(diff的前缀和)(定义一个存宝藏位置的数组res(bool) )。curr初始值为0,定为前缀和,然后resi用来存curr大于0的位置。举个例子:图中3,8表示的是这些位置是要标记的。我们可以发现,前缀和到-1正好变成了0。所以正好可以实现需求。最后我们只需要反着输出res(!)即可。

相关推荐
SL_staff1 小时前
JVS-Logic:从页面配置工具到企业级业务逻辑中枢的技术演进
java·算法·全栈
陌シ未央ゞ1 小时前
基于BM25算法和RRF实现的混合索引(java版)
人工智能·spring boot·后端·算法
renhongxia11 小时前
数字孪生不止在工厂:能源、医疗与农业
人工智能·深度学习·算法·机器学习·数字孪生
Navigator_Z1 小时前
LeetCode //C - 1250. Check If It Is a Good Array
c语言·算法·leetcode
CodeRecycle3 小时前
Python 自动配置 pip 支持库(通过 Windows Bat 脚本)
算法
liliangcsdn3 小时前
特质偏度因子的计算示例和分析
算法
荆棘鸟智能4 小时前
无人机遥感图像实时拼接算法工程实践:从特征提取到全景融合的完整技术链路
算法·无人机
6Hzlia4 小时前
【Classic 150 刷题计划】 LeetCode 58. 最后一个单词的长度 | C++ 极简反向遍历与单变量状态机
算法
AgentMaster4 小时前
企业如何应用智能客服?5 个典型场景的技术架构与实施路径
大数据·算法