1.Bash(巴什博弈)
有一堆石子共有n个。AB两个人轮流拿,A先拿。每次最少拿1颗,最多拿m颗,最后取完者获胜。
取胜策略:拿掉部分物品,使对方面临看k(m+1)的局面。
void solve(int n,int m){
//n%(m+1)!=0则先手赢,反之后手赢
printf("%c\n",n%(m+1)?'A':'B');
}
2.Wythoff(威佐夫博弈)
有2堆石子。AB两个人轮流拿,A先拿。每次从一堆中取任意个或从2堆中取相同数量的石子,但不可不取,最后取完者获胜。
性质:我们称Wythoff中的必败态为奇偶局势(ak,bk)
①任何自然数都仅包含在一个奇偶局势中;
②an+1=前n组必败态中未出现过的最小正整数;
③如果(an,bn)为必败态,则bn = an + n;
结论:an=⌊n*(1+√5)/2⌋,bn=an+n(n=0,1,2…n)。
故判断(a,b)为奇偶局势,只需要比较(b-a)*(1+√5)/2)==a即可 (其中a<b)。
double g=(sqrt(5)+1)/2;
void solve(int a,int b){
if(a>b)swap(a,b);
int t=(b-a)*g;
if(t==a)printf("B\n"); //必败态(a,b)为奇偶局势
else printf("A\n");
}
3.Nim(尼姆博奕)
有N堆石子。AB两个人轮流拿,A先拿。每次从一堆中取任意个,但不可不取,最后取完者获胜。
结论:所有堆石子数量异或不为0,则先手胜,反之后手胜。
void solve(){
int ans=0;
for(int i=1;i<=n;i++)
ans^=s[i];
//ans不为0则先手赢,否则后手赢
printf("%c\n",ans?'A':'B');
}