===== codeforces 642 div3 ===== ==== AB:略 ==== ==== C ==== 题意:给定一个方格阵,边长为奇数,每次能做一个操作,就是将一个字的数(i,j),移到(i+1,j)或(i,j+1)或(i-1,j)或(i,j-1)或(i+1,j+1)或(i+1,j-1)或(i-1,j+1)或(i-1,j-1)。问最少多少次操作可以把所有数都移到一个格子。 解:公式题,题目都疯狂暗示了边长为奇数,那肯定最少步数在中心的那个个子产生啊,为什么不知道,对称最美,然后推一下公式即可。 ==== D ==== 题意:大致是一个模拟题,给一个全是0的序列,每次取序列中,0最多的一段连续序列[i,j],将中间那个数(如果序列只有偶数个,则向下取整)变成操作号。问操作到最后序列是啥 解:开一个优先队列,存一个pair型结构体,重定向大于号,然后模拟到优先队列为空。 ==== E ==== 题意:给一段01串,再给一个数k,一次操作可以将1变成0,问多少次操作后,可以使序列满足性质:对于序列中出现的任意两个连续的1,它们的间隔都为k; 解:dp题,当时我看错题了5555……,后来感觉还可以,不是很难,用dp[i]表示第i个出现1则需要的移动次数,首先判断一下使不是都是0,是就直接输出0,否则开始dp,首先与处理出前i个数中1的个数,对于dp[i]有两种情况,就是i前面没有出现过1,或者前面出现过1。下面借着代码说明一下: for(int i=1;i<=n;i++) { dp[i]=0x7fffffff; if(i>=k+1) dp[i]=min(dp[i],dp[i-k]+sum[i-1]-sum[i-k]); dp[i]=min(sum[i-1],dp[i]);//在i点有灯开只有两种情况,i-k有灯开,或者i前面没有灯开 dp[i]+=(a[i]=='0'); ans=min(ans,dp[i]+sum[n]-sum[i]); }