2024-09-24 模拟赛题解

lrx 的蒟蒻 blog / 2024-09-25 / 原文

\(0+30+0+0=30\),挂惨了。
比赛链接:http://172.45.35.5/d/HEIGETWO/homework/66f10eb944f0ed11b057157e

A - 依依寺

题意:

现在有 \(a\)\(0\)\(b\)\(1\)\(c\)\(2\),有两个人 F 和 S,F 先手,每次操作选择一个数,若所有操作累计的和 \(s\)\(3\) 的倍数,那么操作的那一方输,如果某一方不能操作,那一方也输。两人轮流操作,若两人都已最优操作操作,求谁必赢。

思路:

显然先手不能先选 \(0\),如果不考虑 \(0\),那么只可能如下选择:

  • \(1-1-2-1-2-\cdots\)
  • \(2-2-1-2-1-\cdots\)

在考虑 \(0\) 的情况:选择 \(0\) 只会改变先后手关系,所以只需要考虑 \(a\) 的奇偶性。

\(a\) 为偶数,那么 \(0\) 就没有用,根据上面的性质,当 \(a,b\ge 2\) 时,F 一定能赢,边角情况随便讨论一下即可。

\(a\) 为奇数,那么 \(0\) 指挥改变先后手关系,考虑 \(a,b\) 较大且 \(|a-b|\) 较大的情况。

  • 若 F 先拿元素较少的一堆,接下来就是轮流选 \(12\),S 可以取一个 \(0\),这样 S 就赢了。
  • 若 F 先拿元素叫多的一堆,接下来就是轮流选 \(12\),S 肯定不会取 \(0\),否则 S 就输了,但是 F 可以选 \(0\),那么 F就赢了。

综上,这种情况的 F 必赢。边角情况在代码中给出。

代码:

#include <bits/stdc++.h>

using namespace std;

int T;
long long a, b, c;

bool C(long long a, long long b, long long c) {
  if (a % 2) {
    if (b == 0) {
      return c && c != 1;
    } else {
      return b - 1 > c || c - 1 > b;
    }
  } else {
    if (b == 0) {
      return c == 1;
    } else if (b == 1) {
      return 1;
    } else {
      return c;
    }
  }
}

int main() {
  freopen("yiyi.in", "r", stdin);
  freopen("yiyi.out", "w", stdout);
  ios::sync_with_stdio(0), cin.tie(0);
  for (cin >> T; T; T--) {
    cin >> a >> b >> c;
    cout << (C(a, b, c) ? "First\n" : "Second\n");
  }
  return 0;
}

B - 武义寺

题意:

给定 \(n\),随机生成一个排列 \(p_n\),定义 \(val(p)\)\(p\) 中的最小的 \(i\) 使得 \(i>p_i\),求 \(val(p)\) 的期望。

思路:

由于每一个