HDU 1729 Stone Game【SG函数】

时间:2021-12-23 16:24:58

以下转载至:长春理工大学赵小舟博弈论ppt

题目大意:

1、有n个盒子,每个盒子都有它的容量s

2、在游戏开始时,每个盒子里都有一些石子

3、双方轮流进行游戏,向一个盒子投入n个石子,其中n不能大于当前盒子中石子数量的平方,投入后盒中石子数不能超过其容量

例:如果现在盒中有3个石子,则可以向里投1-9个

4、谁不能向任何盒中投石子为负

给出n个盒子的初态, 问在双方均为最优策略时先手者是否能取胜

思路:

s=20的情况(k代表题目中的c)

HDU 1729 Stone Game【SG函数】

规律: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 ;
while(){
int l=,r=sqrt(s),k;
while(l<=r){
k=(l+r)>>;
if(k*(k+)<s)
l=k+;
else
r=k-;
}
k=r;
if(k==c) return ;
else if(k<c) return s-c;
s=k;
}
}
int main(){
int n,s,c,ans,cas=;
while(~scanf("%d",&n)&&n){
ans=;
while(n--){
scanf("%d%d",&s,&c);
ans^=SG(s,c);
}
printf("Case %d:\n",++cas);
if(ans) puts("Yes");
else puts("No");
}
return ;
}