取石子游戏:
地上有n堆石子,每人每次可从任意一堆石子里取出任意多枚石子扔掉,可以取完,不能不取。每次只能从一堆里取。最后没石子可取的人失败
结论:n堆石子异或和=0时先手必败,否则先手必胜
必胜态:当前局面,先手必胜
必败态:当前局面,先手必败
用n元组(a1,a2。。。an)表示每一个局面
初始局面只有一堆石子,则甲有必胜策略
初始局面有两堆石子,且两堆石子数目相同(?),则乙有必胜策略
局面的加法和分解
(a1,a2,。。。,an)+(b1,b2,。。。,bm)=(a1,a2,。。。,an,b1,b2,。。。,bm)
若初始局面可以分成两个相同的“子局面”,则乙有必胜策略
若A和B一胜一负,则S胜
若A负和B负,则S负
若A胜B胜,则不确定
一个局面不能被简化称为最简局面
最简局面中不会有两堆相同的石子,故可以用同一个集合来表示最简局面
例题:NIM游戏
有n堆石子。A,B两人轮流拿,A先拿。每次只能从一堆中取若干个,可将一堆全取走,不可不取,拿到最后一颗石子的人获胜。给出n及每堆石子的数量,问最后谁能赢得比赛
#include<bits/stdc++.h> using namespace std; int main() { int n,temp,ans=0; cin>>n; for(int i=1;i<=n;i++) { cin>>temp; ans^=temp; } puts(ans==0?"B":"A");//若条件为真则输出:前的元素 return 0; }
NIM改:每次最多只能取k个
可以将每堆石子mod(k+1)
结论:
若A和B相同,则A+B负——若a和b相等,则a+b=0
若A胜B负,则A+B胜——若a=1,b=0,则a+b=1
若A负B胜,则A+B胜——若a=0,b=1,则a+b=1
若A负B负,则A+B负——若a=0,b=0,则a+b=0
对上述结论简化:
若a和b相等,则a^b=0
若a=1,b=0,则a^b=1
若a=0,b=1,则a^b=1
若a=0,b=0,则a^b=0
Anti-Nim
取完最后一个石子的玩家是输家
不能直接简单的将NIM游戏结论取反
例题:
桌上有n堆石子,约翰和他哥哥轮流取石子,每人取石子时可任意选取一堆石子,在这堆石子中取任意多的石子,不能一粒石子也不取,取到最后一粒石子的人输,约翰先取。
富裕堆:石子数>1的堆
先手胜: