以下转载至:长春理工大学赵小舟博弈论ppt
题目大意:
1、有n个盒子,每个盒子都有它的容量s
2、在游戏开始时,每个盒子里都有一些石子
3、双方轮流进行游戏,向一个盒子投入n个石子,其中n不能大于当前盒子中石子数量的平方,投入后盒中石子数不能超过其容量
例:如果现在盒中有3个石子,则可以向里投1-9个
4、谁不能向任何盒中投石子为负
给出n个盒子的初态, 问在双方均为最优策略时先手者是否能取胜
思路:
s=20的情况(k代表题目中的c)
规律:k(k+1)<s时k的最大值为sg=0的一点,其后的sg值从s-k-1开始递减。
二分寻找k的最大值,并将其赋给s,与盒中初始石子数量比较,若k大,可直接得出sg值,若小,将k赋值给s,继续寻找。
其实当寻找更大的s的sg值情况时,可以发现,从k-1~2的sg指从1依次递增。
#include<stdio.h> #include<string.h> #include<math.h> int SG(int s,int c){ if(!s||!c) return 0; while(1){ int l=0,r=sqrt(s),k; while(l<=r){ k=(l+r)>>1; if(k*(k+1)<s) l=k+1; else r=k-1; } k=r; if(k==c) return 0; else if(k<c) return s-c; s=k; } } int main(){ int n,s,c,ans,cas=0; while(~scanf("%d",&n)&&n){ ans=0; while(n--){ scanf("%d%d",&s,&c); ans^=SG(s,c); } printf("Case %d: ",++cas); if(ans) puts("Yes"); else puts("No"); } return 0; }