Educational Codeforces Round 160 (Rated for Div. 2)
内容提要
本文介绍Codeforces教育轮160(Div.2)三道题的解法:A题将数字串拆成两个递增数,在第二个非零位前拆开;B题对01串通过贪心交换或删除使新串与原串每位不同,无法交换时删除其后所有字符;C题多重集凑数,按二进制从高位到低位处理进位,判断能否凑出目标值。
延伸解读
A题拆分的贪心依据
A题要求将数字串拆成两个递增数。解法指出在第二个非零位前拆开即可。这是因为第一个非零位作为第一个数的开头,第二个非零位作为第二个数的开头,能保证第二个数位数尽可能多,从而更可能大于第一个数。若这样拆分后仍不满足a[0] < a[1],则不存在其他拆法,输出-1。
B题删除策略的边界
B题允许交换(无代价)和删除(有代价),目标使新串与原串每位不同。贪心策略是从左到右尽量用交换匹配相反字符,一旦某个位置无法交换,则必须删除该位置及其后所有字符。因为删除单个字符会导致后续字符前移,无法保证每位不同,所以直接删除后缀是最优选择。
C题二进制进位模拟
C题的多重集由2的幂组成,询问能否凑出目标值。解法从高位到低位处理,维护一个“需要”值last,初始为0。对于每一位,last左移并加上目标值的当前位,然后减去该位可用数量cnt[i],若结果为负则置0。最终last为0表示可以凑出。这模拟了二进制进位过程,确保低位不足时由高位补充。
Q&A
Educational Codeforces Round 160 (Div. 2) 的 A 题 Rating Increase 要求做什么?
给定一个数字串,将其拆成两个数,要求第一个数小于第二个数,并输出一种拆法。
A 题 Rating Increase 的解题思路是什么?
找到第二个非零数字的位置,在该位置前拆开,这样第一个数尽可能小,第二个数尽可能大,是最优拆法。
B 题 Swap and Delete 中,如何操作才能使新字符串与原字符串每位都不同?
从头开始尽量使用交换操作,如果某个字符无法通过交换解决,则删除该字符及其后面的所有字符。
B 题 Swap and Delete 的答案是如何计算的?
统计原字符串中 0 和 1 的数量,遍历字符串,对于每个字符,如果存在相反字符则消耗一个,否则答案就是剩余字符数(即从当前位置到末尾的长度)。
C 题 Game with Multiset 中,如何判断能否凑出目标值?
从二进制高位到低位处理,维护进位,对于每一位,计算当前需要的数量,如果集合中该位的数量不足,则向低位借位,最终判断是否恰好凑出。
C 题 Game with Multiset 的代码中,last 变量代表什么?
last 表示当前位需要从低位进上来的数量,初始为 0,每次循环左移一位并加上当前位的需求,然后减去该位已有的数量,取非负值。