2024-09-24 模拟赛题解
\(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)\) 的期望。
思路:
由于每一个