这周事情有些多,学习时间比较零碎,所以就不写日期了。
Codeforces
Educational Codeforces Round 32
A - Local Extrema (0:02, +)
遍历一次即可。
B - Buggy Robot (0:16, +2)
一开始以为就没看在眼里,直接dfs搜上去,超时了。
事实上,其实只要再想一下就可以发现,想要回到原地,L和R必须两两配对,U和D必须两两配对。最后的答案ans = ( min(num[L], num[R]) + min(num[U], num[R]) ) * 2。
C - K-Dominant Character (0:28, +3)
可以认为,使最小,那么我们一定选择出现频率最高的字母。枚举所有出现次数最多的字母,然后判断间隔最大值后取最小即可。
也可以二分查找,虽然感觉这道题里其实没太大必要。
D - Almost Identity Permutations (0:49, +)
随便推一推就可以推出来式子。一开始没注意,导致一直在推后面的系数(先看数据范围的重要性)。
写公式太麻烦,就不把公式写在这里了。
E - Maximum Subsequence
通过这道题目接触了一个重要的思想,叫meet-in-the-middle。题目本身没有什么特别好的做法,就是枚举每一个数是否选择,来看最终的结果好不好。但是这样复杂度在,铁T无疑。但是我们注意到,这道题求模数最大,可以用meet-in-the-middle的思想,先求左边一半的模数情况,再求右边一半的模数情况,然后将两边的情况整合到一起。这样搜索的时间复杂度一下子就降到了,才40w左右。然后我们要整合,对于前一半每一个可能的模数,我们看能不能凑到m-1或2m-1,在后一半的数组二分即可。所以整体复杂度大约就是。
Codeforces Round #768 (Div. 2)
A - Min Max Swap (0:04, +)
比较简单的签到题,把大的挪到一边小的挪到一边。
B - Fun with Even Subarrays (0:24, +3)
比赛过程中不知道怎么想的,会想到2的幂数上去,并因为这个WA了几发,实属zz行为。
最后形成的序列的每一个元素的值一定和原数组最后一个元素相同,往前复制就行了。
C - And Matching (1:16, +1)
是一道很有意思的题目。其实很快就看出来,当k<n-1时,将和为n-1的数两两组合,然后把0和k互换就可以了。当k=n-1时,只有n=4的时候是无解的,当时看到这个之后,猜其他的时候也无解,兴高采烈交上去,然后WA了。后来发现n=8,k=7是有解的,换了换位置,凑出每一位的1就可以了。
D - Range and Partition
也是一道很有意思的题目,虽然赛中没有做出来。
首先假设这个范围确定之后,考虑我们如何来划分k个范围。
考虑将范围以内的数设为1,范围以外的数设为-1。得到数组后,求前缀和数组。如果这段数在范围内的数量比不在范围内的数量多,那么这一段的元素的和一定为正。那么我们找到的分段点处在前缀和数组中的值一定是递增的。而且我们一定可以找到1,2,...,k的子序列作为这k段的分段点。也就是说,如果能够分成k组符合要求的序列,前缀和数组在n处的值一定是大于等于k的。
如果前缀和数组在n处的值大于等于k,那就意味着,令a为范围内的元素个数,b为不在范围内的元素个数。那么意味着a-b>=k。即,我们只需要求出整个序列中在范围内的数的数量,就可以知道这个序列在这个范围中能不能符合要求了。而求这个范围的元素的数量,用二分求端点下标,是级别的。
现在考虑如何求得这个长度最小的区间。
我们对每一个i(i: 1->n),都来一次二分,以i为左边界,二分到最小的右边界,check的方式如上述。当左右边界相等时,这个范围一定可以作为整体的最优答案。
找到范围后,将划分的区间输出即可。
整体的时间复杂度是。
Coder-Strike 2014 - Finals (online edition, Div. 2)
用零碎时间VP的,没有用CF上的计时器,而是用自己手机计时。所以CF上没有这一场的比赛记录。
Score: 2858, Rank: 23
A - Pasha and Hamsters (0:04, +)
既然保证一定有答案,那就第一个人喜欢的都给第一个人,剩下的都给第二个人。
B - Start Up (0:14, +2)
找出对称字母,然后看是不是回文串就行了(我是鼠标,中间的字母是不是对称的没判,WA了两发)
C - Online Meeting (0:57, +1)
无比离谱的多重判断题目!真的是运气很好,突然想到了一个自己疏漏的地方,改进去过了。
这个题的情况比较复杂,我现在也有点记不得所有的情况了,不过就是各种判断,其实也没什么意思。当时比赛有很多人这个题目没有做出来,这个判断比较恶心(可能就是我菜)。
D - Bug in Code
很好的题目!其实VP的时候已经几乎想到这个题目怎么做了,可是实现的方式的复杂度一直很高,所以没能实现。
没想到要在图上做文章!把给的点对之间连一条边,用一个点的度数表示这个点被多少人认可。事实上就是要找两个点受到的认可数大于等于k的点对个数。那么就枚举每一个点,先让和这个点相连的点删除与自己相连的边的度数,然后统计度数符合两个点的总度数大于等于k的点的个数。这里要将相同度数的数量作为信息存储,然后排序,用线段树维护。每次删除点的度数、恢复点的度数、查询区间和的操作,都是级别的。最后这个点的答案就是符合要求的度的范围内的点的个数。
要注意的就是,如果这个点的度数也在这个范围内,要把自己减掉。
(读入量大,cin和cout会T....)
Deltix Round, Spring 2021 (Div. 1 + Div. 2)
A - Game of Life
不得不说,光是A题就给我当头一棒,只因为自己是鼠标没有进行初始化(乐)。
B - Lord of the Values
这个题蛮好,我没想到。其实题目中有暗示:既然是偶数个数的数组,那么可以优先朝着两个两个处理的方向去思考。发现,对于任意两个数对(a, b),一定可以通过操作序列[1, 2, 1, 2, 1, 2]变成(-a, -b)。这样平均一个数进行3次操作,最终次数是3n,一定小于5000。
只能说:真的没想到!下次尽力看懂题目中给的各种暗示。
C - Compression and Expansion
遇到1,就往右建分页,遇到不连续的,就往前找,看是哪一个数的后续。用这样的思路不断找就可以了。