上大学以来打的第一场比赛,也是第一次打CF,就碰到了Unrated,感觉离1800分的目标还很远。

第一次碰CF属实是没经验,签到完第一道题想交上去,一直点submit都没反应,研究了几分钟才发现是没选题目,提交上去后在队列里评测了很久才评测完,打开结果一看竟然CE了,又查了可能十几分钟的错才发现语言选错了,C11竟然不是C++11,再交一遍就过了,第一题水题搞了我快一个小时。最后做完AB也很迟了就直接关了去睡觉了。

以下是做A,B题的思路:

A. Countdown

题面意思:有个钟,钟上有N位数字,每位数字初始是0-9,你能从两个操作中选一个来做:1.将整个钟的数字减去1,2.任选两位交换他们的数字。要求求出使得钟上所有数字都变为0的最小操作数。

贪心就能做了,设钟上数字数组为a[n],a[n]就是个位,那么个位的数字是要优先让他变成0的,ans+=a[n],对于其他位的数字,如果是0就不用操作,大于0就要先把这个数换到个位再把它变成0,即ans+=a[i]+1,O(n)。

B. Swaps

题面意思:有两个数组a,b,长度都为n,数组a中的数都是奇数,为1,3,5,7……2n-1,数组b中的数都是偶数,为2,4,6,8……2n。数组中的数的排列顺序不一定从小到大排。每次操作能选择一个数组交换相邻两个数的位置。求使得a的字典序小于b的最小操作数。

字典序这个单词还是我百度翻译才知道的,这题时间控制挺严格的感觉不是O(n)应该是会挂的,好在n是小于1e5的,我就想到可以利用计数排序和动态规划的思想。具体来说,就是设置3个数组a,b,pos。a[i]是指数2i-1在数列a中的位置,b[i]是指数2i在数列b中的位置,pos[i]是指对2i-1这个数(也就是a[i])在B中比它大的第一个数的位置。

既然要字典序更小,那么只要a,b两个数列的第一位a比b小就好,那么从数列a来看,若将第i个数移动到第1位要操作i-1次,同时为了字典序更小要将在数列b中比它大的第一个数移动到第1位来,要操作pos[i]-1次,所以ans=min(ans,a[i]+pos[i]-2)。

pos[i]如何得到?应该从最大的数开始往前倒推,对2k-1这个数而言,pos[k]=min(pos[k+1],b[k])。由此可以得到O(n)的算法。

 

就做了这两题,就这样吧