• 博客园logo
  • 会员
  • 众包
  • 新闻
  • 博问
  • 闪存
  • 赞助商
  • HarmonyOS
  • Chat2DB
    • 搜索
      所有博客
    • 搜索
      当前博客
  • 写随笔 我的博客 短消息 简洁模式
    用户头像
    我的博客 我的园子 账号设置 会员中心 简洁模式 ... 退出登录
    注册 登录
L&King
有何不可!
   首页    新随笔    联系   管理    订阅  订阅

HDU 1729 Stone Game【SG函数】

以下转载至:长春理工大学赵小舟博弈论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:\n",++cas);
        if(ans)    puts("Yes");
        else    puts("No");
    }
    return 0;
} 

 

posted @ 2016-08-12 15:52  L&King  阅读(298)  评论(0)    收藏  举报
刷新页面返回顶部
博客园  ©  2004-2025
浙公网安备 33010602011771号 浙ICP备2021040463号-3