CF Round 700(Div2) 解题补题报告
这把被吊锤就离谱,尤其是B题写的都失了智了
A题 Yet Another String Game(简单博弈)
给定一个字符串 ,两个人 和 玩一个小游戏,每个人轮流出手,将某个位置的字符变换一下(不能和原来相同),每个位置仅能更改一次。 的目标是使得最后的字符串的字典序尽量大, 则相反。如果两人均采取最佳策略,问最后 会变成啥。
看完题目,看下样例,答案就很显然了:
- 两个人都会尽可能选靠前的字符进行修改
- 对于 ,为了使字符串字典序尽量大,肯定是能改成 就改,改不了(原来就是 )就改成
- 对于 ,思路也类似
没啥好说的,具体看代码
B题 The Great Hero (思维)
有个英雄,每次攻击伤害为 ,自身血量为 。现在有 个怪物,第 个怪物伤害为 ,血量为 。
现在英雄每回合选一个怪物与之对战,一回合下来,两个人各自减少对应的血。如果谁血量小于等于 ,那么他就死了。
现在想要判断,能不能干掉全部怪兽(和最后一个怪兽同归于尽也行)
显然必须消灭全部怪兽,那就一个一个打就是了,看看能不能全部打掉
这样写了一发程序,然后荣耀的 了
这时候群里面有大(han)佬(pi) 说,要排序,要排序!
我一听,确实,是这样的,打怪的顺序对于我们确实有影响,例如下面这组数据:
很显然,如果我们先和第一个怪物打,那就会和他同归于尽,所以应该先和第二个打,这样才能将怪兽全部击败
(一种贪心策略:对于某些怪兽,如果注定和他同归于尽或者大批掉血啥的,我们尽量往后拖,然后先打战斗力低的)
对于第 个怪兽,我们可以将 转变为它可以挨英雄打的次数,也就是 ,然后这个怪物战斗力就是 ,按照这玩意排序,然后顺着打就完了。
但我们有找到了一组反例:
这数据已经排好序了,但是显然打第三个怪物会 ,但是我们应该先打第三个,然后和第二个同归于尽才是最佳策略。
懂了, 相同时候,把 小的排在后面
不好意思,又 了,我们可以找到这样一组反例(对上面那个样例修改一下):
我就问,你现在还能怎么排?
我相信有不少大佬还能排,而且比赛的时候能过(随后被 的体无完肤),但是我们现在应该跳出这个思维了:按照特定思路贪心并且排序,真的是正解吗?
其实经过上面的一系列操作加上 之后,我们基本上已经清楚了消灭所有怪兽的一种基本策略:
- 先消灭 个怪兽,并且保证消灭完之后英雄还活着
- 消灭最后一个怪兽,要么全身而退(打完还活着),要么同归于尽
对于全身而退的方式,我们上面所有的方案都没问题,重点在于这个同归于尽:在血量不够的情况下,尽量最优化,和最后一个怪物换掉
这东西是没法贪心选出来的,但是我们发现,这东西似乎可以线性枚举(就离谱):枚举和哪一个怪兽最后打,然后看看别的 个怪兽能不能全部消灭,然后和最后一个怪兽尝试互换一波
越说越迷糊了,直接上代码了(昨晚把我折磨傻了):
C题 Searching Local Minimum (二分,交互题)
这是一个交互题。
给定一个 到 的排列 ,但是我们只知道 的大小,不知道排列的具体情况。
我们每次可以向评测姬询问,问 是多少 ,询问次数不得超过 次。
现在我们希望找到一个正整数 ,使得 且 (我们默认 )
好,这题重新让我认识了二分(就离谱)
次找 规模的数据,不用怀疑,二分没跑了,主要是:这 B 玩意咋二分?
我们不妨设答案区间为 ,也就是该区间必然存在 ,使得
我们令 ,查询 和 的值。
证明:当 时,区间 必然有解:
我们可以反证,假设该区间无解:因为 作为先决条件必然成立(如果不懂就先接着看,待会就懂了),所以为了保证无解, 在区间 上必须单调递减,否则必然能够找出反例。尴尬的是,此时恰好出现 的情况,说明 是一个可行解。
反证矛盾,证明正向结论成立。
反之,如果 时,区间 必然有解,证明同上。
如果严格遵守这套递归流程,那么可以保证边界条件成立。
好了,一套数学证明下来,我们便找出了二分策略,很显然,询问次数不会超过 次。
这题难度我给一分,因为我一份抵别人一伯分(逃
D1题 Painting the Array I (贪心)
给定一个数列 ,尝试将其分成两个数列 和 (这两个数列允许是空的)。
现在给定一个操作 :对于一个数列,在不排序的情况下将其去重(也就是只去重那些相邻的),然后剩下来的那个数列的长度,称其为该数列的 值。
现在尝试找出一种分法,使得 最大,并且输出该最大值。
这题目似乎只能贪心来写就离谱。
我们不妨记 的最后一个元素是 , 的最后一个元素是 , 线性扫描数组 ,记扫描到的数字是 。
显然有这样的贪心策略(虽然这玩意证明就离谱):
-
当 时就把 插到 后面,反之亦然;如果,那就随便插
这个应该比较显然了吧,这种插法但凡修改一下,都不会使得答案更优
-
当 时,这时候理论上插在谁后面都行,但是这里有个小问题:
打个比方,例如数列 ,此时 ,,这时扫到 ,显然,我们应该把这个数插到 而非 后面。
这里引入一个 函数,例如 表示 下一个值为 的下标。例如上述情况下,
有个似乎比较显然的结论:当 时,虽然两种插法都行,但是最好当 时插在 后面, 时插在 后面(赶紧堵住,防止到时候重复)。
这玩意只能说是靠直觉感受出来的,但是证明并不显然。实际上,我看了官网的题解证明,还以为点错了题,点进了 div2 D。所以说这玩意感受下就好,不要强求证明了(反正我肯定不会
现在考虑下如何维护这个 了,毕竟暴力的复杂度是 ,铁超时。我们可以开一个 数组维护一下,这样就可以 从后向前扫一遍就出结果了(详情见代码)。
这里有个小细节:为了方便,我是一开始默认将前两个数给分别分到 和 里面的,但是在第 8 个点 了,(因为前两个数在部分情况下应该放在一个数组里面,虽然我还没有找到一个足够简单的例子),所以我又稍微改了下,变成下面这段代码(不仅思维难度高,而且代码本身还有亿些小细节):
D2题 Painting the Array II (贪心)
这题和上一题的区别在于,这里是尝试使得表达式的值最小。
不会,告辞。
__EOF__

本文链接:https://www.cnblogs.com/cyhforlight/p/14393045.html
关于博主:评论和私信会在第一时间回复。或者直接私信我。
版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!
声援博主:如果您觉得文章对您有帮助,可以点击文章右下角【推荐】一下。您的鼓励是博主的最大动力!
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· go语言实现终端里的倒计时
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列01:轻松3步本地部署deepseek,普通电脑可用
· 按钮权限的设计及实现
· 25岁的心里话