思路
因为总共有 \(K+1\) 堆,所以我们重点考虑当前最小值。
设 \(m=\min A_i\),并且令 \(d=\sum A_i-(K+1)m\),也就是先把所有堆都削到最小值 \(m\) 后,还额外剩下多少石子。
先看 \(d<K\) 的情况
如果 \(d<K\),说明除了每个堆公共拥有的 \(m\) 层以外,额外石子的总数不到 \(K\)。
这时想完整进行一回合的 \(K\) 次操作,主要依赖这 \(K+1\) 个都还非空的堆。
可以把每一层看成 \(K+1\) 个石子。
每一回合需要进行 \(K\) 次操作,因此在这种接近“所有堆一样高”的状态下,每回合本质上可以消掉一层中的 \(K\) 个堆,只会留下一个堆继续存在。
于是游戏的胜负只和最小值 \(m\) 对 \(K\) 的余数有关。
当 \(m\equiv 0\pmod K\) 时,这是后手必胜状态。
因此如果同时满足 \(m \bmod K=0\) 以及 \(d<K\) 那么 Bob 获胜。
为什么其他情况都是 Alice 必胜
如果 \(d\ge K\),说明最小层以上至少还有 \(K\) 个额外石子。
Alice 可以利用这些额外部分调整局面,使其进入前面的后手必胜状态。
而如果 \(m\not\equiv0\pmod K\) Alice 也可以通过第一步把最小高度调整到 \(K\) 的倍数,并控制额外部分,使局面变成 Bob 的必败态。
因此所有不满足 \(m \bmod K=0\) 且 \(d<K\) 的情况都是 Alice 必胜。
最终结论就是:
如果 \(m \bmod K=0\) 并且 \(\sum A_i-(K+1)m<K\) 输出 Bob,否则输出 Alice。
如何想到的
因为一回合必须进行恰好 \(K\) 次操作,而一共有 \(K+1\) 堆,所以可以先关注“所有堆共同拥有的部分”。
把每个堆都减去最小值 \(m\) 后,原来的局面可以拆成:
- \(K+1\) 个高度都为 \(m\) 的基础部分;
- 总数为 \(d\) 的额外石子。
如果 \(d<K\),这些额外部分甚至不足以单独支撑一整回合,所以胜负基本由这 \(K+1\) 个等高堆决定。
这时每回合进行 \(K\) 次操作,而一共有 \(K+1\) 个非空堆,因此可以把过程理解成不断“消耗一层”,于是自然会想到观察 \(m\) 对 \(K\) 取模。
再继续分析发现,只有当 \(m\) 是 \(K\) 的倍数并且额外部分少于 \(K\) 时才是后手必胜态,所以就得到了这个判定。
代码
#include <bits/stdc++.h>
#define rep(i,j,k) for (int i = (j); i <= (k); i ++)
#define per(i,j,k) for (int i = (j); i >= (k); i --)
#define uint unsigned int
#define ll long long
#define ull unsigned long long
#define db double
#define ldb long double
#define mkp make_pair
#define eb emplace_back
#define e_ emplace
#define ls (p << 1)
#define rs (p << 1 | 1)
//#define int ll
using namespace std;
const int N = 2e5 + 5;
//const int MOD = 998244353;
//const int MOD = 1000000007;
const int INF = 0x3f3f3f3f;
const ll LINF = 4e18;
int T;
int k;
int a[N];
signed main () {
//freopen (".in", "r", stdin);
//freopen (".out", "w", stdout);
ios::sync_with_stdio (0);
cin.tie (0);
cin >> T;
while (T --) {
cin >> k;
int m = INF;
ll s = 0;
rep (i, 1, k + 1) {
cin >> a[i];
m = min (m, a[i]);
s += a[i];
}
ll d = s - 1LL * (k + 1) * m;
if (m % k == 0 && d < k) cout << "Bob\n";
else cout << "Alice\n";
}
return 0;
}
复杂度
每组数据只需要遍历一次数组。
时间复杂度为 \(O(K)\)。
因为所有测试中 \(K\) 的总和不超过 \(2\times10^5\),所以总复杂度为 \(O(\sum K)\)。
浙公网安备 33010602011771号