[题解] AtCoder ARC225 B. Independent Nim
[题解] AtCoder ARC225 B. Independent Nim
TAG: 博弈论,构造,思维,AtCoder
题目链接: AtCoder ARC225 B - Independent Nim
题目大意
给定一个只含 0 和 1 的序列。Alice 与 Bob 轮流操作,每次必须选择至少一个值为 1 的位置并将其改成 0,但同一次选择的位置不能相邻。无法操作的人失败,Alice 先手,判断谁有必胜策略。
拿到题目后如何思考
1. 先观察最小局面
先只考虑一段连续的 1:
1:先手可以直接删掉,先手胜;11:由于两个位置相邻,一次只能删掉一个,局面变成1,对手再删掉最后一个,因此先手败;111:先手删掉最左端或最右端,便可以给对手留下11,因此先手胜。
这里第一次出现了真正特殊的结构:11。
单独的一对 11 不能在一次操作中被全部删掉。无论当前玩家删左边还是右边,都一定会留下一个孤立的 1 给对手。
2. 0 把序列分成若干连续段,但不能直接做 Nim 异或
原序列中的 0 永远不会变回 1,所以它们把所有 1 分成若干个极长连续段。
但是,一次操作可以同时在多个连续段中选择位置。因此这些连续段并不是普通意义下“每次只能选择一个子游戏操作”的 Nim 游戏,不能直接计算每段的 SG 值再异或。
真正应该关注的是:能否用一次操作,把整个局面同时整理成一种后手必胜的标准形。
3. 猜测标准形:所有连续段都恰好是 11
由最小局面可以猜测:
当且仅当每个极长连续
1段的长度都等于2时,当前局面是后手必胜态。
也就是说,形如下面的局面都是后手必胜态:
11
11011
11011011
中间可以有任意多个原本就存在的 0,关键只在于每段连续 1 的长度必须是 2。
接下来分别证明标准形不能走到标准形,以及任意非标准形都能一步走到标准形。
为什么若干个独立的 11 不影响先手必胜性质
假设当前所有连续段都是 11。
在一对 11 中,两个位置相邻,所以一次操作最多选择其中一个。又因为一次操作至少要选择一个位置,所以至少有一对 11 会被碰到,并在操作后变成单独的 1。
因此,从“全部由 11 组成”的局面出发,无论怎样操作,都不可能再次得到“全部由 11 组成”的局面。
这也说明一对独立的 11 是一种中性结构:
- 如果原局面已经全部由若干对
11组成,再加入一对独立的11,仍然是后手必胜; - 如果原局面还存在其他非标准连续段,再加入一对
11,也不会消除那个可以控制胜负的非标准段。
所以判断胜负时,可以把已经独立出来的每一对 11 留在原地,不需要主动处理它们。
谁拿到“可支配的 1”,谁就能控制胜负
现在考虑某个长度不等于 2 的连续 1 段。目标是在一次操作后,让它剩下的每个连续段都恰好为 11。
下面的构造中:
1表示这个位置保留;0表示选择这个原本为1的位置,并在本次操作中将其删除。
按照连续段长度除以 3 的余数构造:
- 长度为 \( 3k \):构造成
(110)重复 \( k \) 次; - 长度为 \( 3k+1 \):构造成
0后接(110)重复 \( k \) 次; - 长度为 \( 3k+2 \):构造成
(110)重复 \( k \) 次,最后接11。
例如:
1 -> 0
111 -> 110
1111 -> 0110
11111 -> 11011
111111 -> 110110
1111111 -> 0110110
构造后的所有 0 之间都隔着两个 1,所以本次要删除的位置两两不相邻,操作一定合法;留下来的每个连续 1 段又都恰好是 11。
长度为 2 时不需要做任何事,直接保留原来的 11 即可。对于其他长度,构造中至少会删除一个位置。
不同极长连续段之间原本就隔着 0,所以可以同时对所有非标准连续段执行上述构造。把各段中要删除的位置合并到同一次操作里,它们仍然不会相邻。
这样,任意不是标准形的局面,都可以一步变成全部由独立 11 组成的标准形。
这里所谓“谁有 1,谁就能控制胜负”,更准确地说是:
谁拿到至少一个没有被固定在标准
11中的可支配1,谁就能利用它完成上述整理,把后手必胜的标准形交给对方。
反过来,如果当前只有若干对 11,当前玩家无论如何都必须拆开至少一对,制造出可支配的单独 1。于是对手又能把局面整理回标准形。
必胜态与必败态证明
令标准形表示“每个极长连续 1 段的长度都为 2”。
标准形是必败态
任意合法操作都至少触碰一对 11,并且在这对 11 中最多删除一个位置,因此操作后一定会出现长度为 1 的连续段。也就是说,标准形的任何后继状态都不是标准形。
非标准形是必胜态
对每个长度不为 2 的连续段,使用上面的周期构造删除若干个互不相邻的位置;长度为 2 的连续段保持不动。一次操作后,整个序列中的连续 1 段都会变成 11,即走到标准形。
因此满足博弈论中必败态的两个条件:
- 必败态的任意后继都是必胜态;
- 任意必胜态都至少存在一种走向必败态的操作。
最终结论为:
- 所有极长连续
1段的长度都为2,Bob 获胜; - 只要存在一个连续段的长度不为
2,Alice 获胜。
全 0 序列中没有任何连续 1 段,也满足“所有连续段长度均为 2”,此时 Alice 无法进行第一次操作,仍然是 Bob 获胜。
复杂度
只需从左到右扫描序列并统计每个极长连续 1 段的长度。
- 时间复杂度:\( O(N) \),每个位置只访问一次;
- 空间复杂度:\( O(1) \),只维护当前连续段长度和答案标记。
代码前说明
cnt:当前尚未结束的极长连续1段长度;f:当前是否仍满足“已经检查过的每段长度都为2”;- 读到
0:说明一段连续1结束,检查cnt是否为0或2,再清空; - 扫描结束:如果序列以
1结尾,还要单独检查最后一段; f=true对应后手必胜态,输出Bob,否则输出Alice。
参考代码
#include<bits/stdc++.h>
using namespace std;
#define endl '\n'
void solve(){
int n;cin>>n;
bool f=1;
int cnt=0;
int x;
for(int i=1;i<=n;i++){
cin>>x;
if(x==1){
cnt++;
}else{
if(cnt!=2&&cnt!=0) f=0;
cnt=0;
}
}
if(x!=0&&cnt!=2) f=0;
if(f) cout<<"Bob"<<endl;
else cout<<"Alice"<<endl;
}
signed main(){
ios::sync_with_stdio(false);
cin.tie(nullptr);
int t=1;cin>>t;
while(t--) solve();
return 0;
}

浙公网安备 33010602011771号