Codeforces Round #693 (Div. 3) 题解(A-G)

AC代码

A. Cards for Friends

(t)为当前能分的份数。

如果满足条件就不断将(w)(2),或者将(h)(2),每次除(2)的时候,(t)可以变为([t + 1, 2t])中的任意一个数。

即假设最大能达到的(t)(T),那么如果(T ge n)则YES,反之则NO。

B. Fair Division

(1)的个数为(c_1)(2)的个数为(c_2)

(c_1)为奇数,则总和也为奇数,必不可能有解。

否则,可以先平分(2)

  • 如果(c_2)为偶数,那么只需要再平分(1)。此时有(c_1)也为偶数,有解。
  • 如果(c_2)为奇数:
    • 如果有(c1 ge 2),则可以用两个(1)来构成一个(2),转换到前一种情况。
    • 反之,则无解。

C. Long Jump

假设(s_i)为从(i)处开始可以获得的分数。

那么有:

  • 如果(i + a_i le n)(s_i = a_i + s_{i + a_i})
  • 反之,(s_i = a_i)

可以看到(s_i)的值只依赖于(a_i)或者下标更大的(s_{i + a_i}),根据式子从(n)(1)求出所有(s_i),再取个最大值就可以了。

D. Even-Odd Game

假设现在操作的是Alice,而剩余元素中最大的值是(x),那么有:

  • 如果(x)是偶数,那么当下直接拿(x)收益最大。
  • 否则,如果就算了剩余元素中最大的偶数(y),然后下一步Bob拿到了(x),Alice在这一轮的收益就是(y - x)为负数。所以不如抢了(x)让Bob拿不到。

这个就是Alice的最优策略,Bob的最优策略可以类推。

然后就是排个序或者用优先队列模拟一下。

E. Correct Placement

比赛的时候细节疯狂出锅,直接心态炸裂。

首先,一个人有两种可能:((w, h))((h, w))。那么其实可以将人看成((w, h, id))((h, w, id))这两个元素。

然后现在只需要考虑第一种情况了,也就是二维偏序。但是因为只需要找到某一个满足条件的(j),所以没有必要真的搞二维偏序。

大概过程就是先所有元素按(h)升序排序,然后依次遍历元素。因为只需要找到某一个符合的元素,所以直接找前面的元素中(w)最小的就好了,然后因为需要(i e j),所以还需要特判一下。这里我是用一个按(w)升序排序的集合(s)来做。

对于第(i)个元素((h_i, w_i, id_i)),先将尚未加入集合且(j < i)(h_j < h_i)的元素((h_j, w_j, id_j))加入集合(s)。因为事先排过序,这一步可以用指针做,均摊(O(1))

因为只需要找到某一个满足条件的(j),所以直接拿(s)的第一个元素就好了。但是还需要满足(id_j)不等于(id_i),这里只需要再特判一下,如果相等就拿(s)中次小的元素。如果拿出来的元素((h, w, id))满足(w < w_i),就可以用(id)去和(id_i)匹配。

F. New Year's Puzzle

赛后看神仙的代码才想出来。我一开始想的是DP,但是看了好多都是直接分类讨论然后判断。

首先,对于每一列,如果这一列有障碍,就将之前的空白都填上。

然后,可以假设再(0)列和(n)列都有两个障碍,这样可以避免边界讨论。

现在,每次填满空缺的时候,都是在两列障碍之间填满。根据这两列障碍的状态去判断是否可能将中间全部填满,以及更新填满之后靠后一列障碍的状态。

这样的依据相当于判断每两个相邻有障碍的列之间的空缺是否能够补满。如果有任何两个相邻的有障碍的列之间填不满,那么必定无解。如果所有相邻的有障碍的列之间都能填满,那也就是有解。

从列号小的障碍开始枚举,然后每次画个图判断一下就完事了。

例如,对于第(c)列,这一列的状态(s)等于这一列障碍的行号之和。

假设上一个有障碍的列为(lc),其状态为(ls)

如果(s = 3),那么必须要有(ls = 3)才有可能能将中间的空缺填满,否则必定会留出一个空。靠后一列状态不变。

如果(s = 1),且(ls = 3),那么([lc+1, c - 1])之间都可以竖着放来填满。靠后一列状态不变。

如果(s = 1),且(ls = 1),那么([lc +1, c - 1])的长度必须要是偶数,不然就填不满;且此时([lc, c])的长度也为偶数。所以现在靠后一列被填满成了两行都有障碍。

G. Moving to the Capital

首先,通过观察可以得到:

  • 题目的条件限制相当于至多走一次非最短路上的边。
  • 沿着最短路走,(d_i)只会继续增大。

考虑使用动态规划解决这个问题。对于节点(u)

  • 自身是可能的答案,所以(dp_u = d_u)
  • 可以走一次非最短路上的边,而之后如果再走最短路上的边,距离只会增大,所以(dp_u = min_{(u, v) in E, d_u ge d_v} (dp_u, d_v))
  • 可以随便走最短路上的边,所以(dp_u = min_{(u, v) in E, d_u < d_v} (dp_u, dp_v))。这里的计算用到的距离更大的点,所以要先处理距离更大的点。

首先单源多汇最短路跑出(d_i),然后对节点按距离降序排下序,最后再跑上述动态规划完事了。

原文地址:https://www.cnblogs.com/zengzk/p/14233326.html