【题解】牛客练习赛86
A.
一句话题意:在纸上写一个数字 n
,双方每次选择 n
的一个因数,然后划掉 n
并在纸上写下 n减去这个数字的差
使之成为新的 n
,最后写数字 0
的人输。Alice
先手,请请你判断谁会获胜。
Solution:
典型的 SG 函数。打表可以发现若 n
是偶数,则先手必胜;若 n
是奇数,则先手必败。
简单证明:显然 n=1
时必败,若 n
为奇数,则一次操作后必为偶数,而 1
是任何数的因数,所以又会变成奇数,故先手必败;反之,则先手必胜。
B.
简单题意:求一个字符串 s
恰好有 k
种还原方式,即满足 A
,B
,C
三个数字视为字符串拼接起来后的结果为 s
且 A+B=C
。如 s="123"
,那么可以还原出 1+2=3
。不能有前导零,可以为 0
。n<=100
,k<=2
。
Solution:
直接按自然数的顺序枚举即可。
C.
一句话题意:有一个货币系统,按贪心策略给取款人发放钞票,即每次都为能取得的面额的最大值。求对于取款金额不超过 b
的方案中,最多能取多少张钞票,输出最大值和相应的取款金额。
Solution:
贪心+递推
好题。
首先由于取款的面额一定,所以选择面额小的钞票越多越好。
引理:对于任意取款金额 c
,若面额最小的钞票取得最多,则取款的张数一定最多。
证明:假设多选一张面额为 1
的钞票,则对于 a_2
剩的钱一定更多,所以 a_2
的张数不会减少,以此类推,直到 a_n
的张数减少,又因为 a_1<a_n
,所以一定更优。证毕。
于是考虑递推,考虑在满足 c<a_i
的前提下以上一次的结果为基础,求到 a_{i-1}
能选到的最大张数。
最后处理答案。二分找到 ps_i<=b<ps_{i+1}
,此时 b<a_{i+1}
,所以不会选择 a_{i+1}
,求出 a_{i}
能选到的最大张数即可。
但是可能存在 b
没有取满的情况,但为了满足引理,此时不能选择更多的 a_{i}
,所以对答案没有影响。
时间复杂度 O(nlogn)
。妙极。
D.
题意:给定一个长度为 n
的序列 a
,可以进行 k
次区间翻转操作,求最终序列最多有多少对相邻两项满足 a_i!=a_{i+1}
。
Solution:
这道题不是很严谨,有点偏思维。我的做法很玄学,但是过掉了。
首先确定答案的上界,假设出现次数最多的数字出现了 x
次,若 x>ceil(n/2)
,则最多有 2(n-x)
对数,否则最多 n-1
对数。
然后这道题可以转化为对于一些数,每次选两个减去 1
,最多操作多少次。这样每次操作贡献为 2
。可以每次选最大数和次大数进行操作。最后如果只剩下一个数,就和其他已经匹配好的数操作,每次贡献为 1
。
下面我们来证明一定存在已经匹配的数与之匹配。
首先一定存在已经匹配的数,否则说明只有一种相同的数字,答案上限为 0
。
其次,假如每一对都存在 a
,而此时序列中只存在连续的 a
,可以发现 a
会交错出现,那么假若首位不是 a
,还可以各翻转一次;否则 cnt(a)>ceil(n/2)
,已经达到了答案上界,所以剩下的操作没有贡献。
__EOF__

本文链接:https://www.cnblogs.com/cqbzly/p/17530329.html
关于博主:评论和私信会在第一时间回复。或者直接私信我。
版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!
声援博主:如果您觉得文章对您有帮助,可以点击文章右下角【推荐】一下。您的鼓励是博主的最大动力!
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 全程不用写代码,我用AI程序员写了一个飞机大战
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· 记一次.NET内存居高不下排查解决与启示
· 白话解读 Dapr 1.15:你的「微服务管家」又秀新绝活了
· DeepSeek 开源周回顾「GitHub 热点速览」