Codechef March Challenge 2020 Division 1 BREAK

其他题看兔队的博客,我懒得更了(


Subtask 1 每一次丢最小的肯定不劣,证明似乎挺显然的来着。


Subtask 2.

先把 \(n \leq 2\) 的情况判掉,只需简单枚举若干情况。

对于 \(n \geq 3\),结论是存在方案的充要条件是以下条件无一成立:

  1. 不存在一个数出现大于等于 \(n+1\) 次;
  2. 先手手上的牌是最大的 \(n\) 张而且它们数字一样;
  3. 后手手上的牌是最小的 \(n\) 张而且它们数字一样。

首先这些条件有一成立则不存在方案是显然的。接下来考虑上述条件不成立时构造一组方案。

首先接下来构造的方案在一轮中双方只会各甩一张牌用于进入下一轮,所以最后一轮谁是先手是确定的。最后一轮的先手方显然更想要点数小的牌,所以我们认为最后一轮先手方倾向小点数、后手方倾向大点数。

在每一轮,如果这一轮先手的牌数不为 \(1\) 则如下操作:选择两个数 \(A<B\) 满足先手手上有至少一张 \(A\),双方手上至少有一张 \(B\),且去掉这两个数之后不存在数出现次数超过一半。后手手上有 \(B\) 的方案优先级更高,也就是尽可能选择 \(B\) 使得后手手上有 \(B\)。因为有上面条件的限制所以这总是可以做到的。接着双方把一张 \(A,B\) 暂时拿出,将先手剩余的牌中先手倾向性最大的牌和 \(A\) 留在手上,其余手牌送给后手,最后先手出一张 \(A\)、后手出一张 \(B\) 结束这个回合。


煮个栗子:第一轮先手和后手分别写在上下两行:

6 5 4
3 2 1

第一轮先手选择 \(A=4,B=6\),然后先手把 \(6\) 丢过去,然后先手丢 \(4\)、后手丢 \(6\) 结束当前回合;

第二轮先手选择 \(A=3,B=5\),然后先手把 \(1\) 丢过去(因为他倾向于更大的,也就是会倾向于 \(2\))丢过去,然后先手丢 \(3\)、后手丢 \(5\) 结束当前回合;

最后先手手上是 \(1\)、后手手上是 \(2\),直接丢完,达成平局。

注意到如果第二轮先手选择 \(A=1,B=2\) 也是合法的,但是这会导致最后一轮先手手上为 \(5\),就不合法了。


接下来解释其正确性。

注意到在第 \(1\) 轮之后第 \(1\) 轮先手手上只有 \(1\) 张牌。我们分两种情况进行讨论:

  • 如果第 \(1\) 轮先手手上的数是当前最大的数,那么接下来 \(B\) 一定等于他手上的数,那么在第 \(2\) 轮结束后,第 \(2\) 轮先手一定可以把剩余的牌中他最想要的牌拿在手上;
  • 如果第 \(1\) 轮先手手上的数不是当前最大的数,那么第 \(1\) 轮的 \(B\) 一定来自第 \(2\) 轮先手,那么在当前所有数中第 \(2\) 轮先手最想要的数一定在他手上,因为第 \(2\) 轮先手最想要的数是第 \(1\) 轮先手最不想要的。而按照上面的策略在第 \(2\) 轮结束后,第 \(2\) 轮先手一定可以把剩余的牌中他最想要的牌拿在手上。

注意到第 \(2\) 轮先手可以把他想要的牌拿在手上,而这张牌是第 \(1\) 轮先手最不想要的牌,故此时第 \(1\) 轮先手手上的牌中一定有他最想要的牌。那么仍然进行上面的操作,可以时刻保证双方最想要的牌均在他们的手上,这样在最后一个回合的时候,这个回合的先手方手上的数就一定比后手方小了。

上一篇:C++ 引用返回


下一篇:HTML5本地存储之Database Storage篇