sg函数 hdu 1729 Stone Game

题目大意:(取石子游戏)有n个箱子,体积为Si,当前箱子里的石子数为Ci。两个人轮流往箱子里放石子,而且每一次放是数量都有限制,不能超过当前箱子内石子数的平方。例如箱子里有3颗石子,那么下一个人就可以放1~9颗石子,直到箱子被装满。当有一方放不下石子时游戏结束,最后放不下石子的人输。

首先空间为20的时候,ci == 20 sg = 0;

   ci == 19 sg = 1;

ci == 18 sg = 2;

ci == 17 sg = 3;

.....................

直到 ci = 4 的时候  sg = 16; 显然此时可以放4 * 4 + 4 == 16个还是赢,所以在 4 ~ 20 范围内  sg(ci,si) = si - ci;

但是当 ci == 3 的时候 sg == 0,之后又是一个循环,所以求sg是个递归的过程;

对于任意一个si,都要找到一个临界点,这个临界点 t 显然得满足   t*t == si - t ;   t--;

 在临界点右边 sg(ci,si) = si - ci;

临界点左边  sg(ci,t);

 

#include <iostream>
#include <cstdio>
#include <cmath>
using namespace std;

int sg( int c, int s){
    int t = sqrt(s);    
    while(t*t + t >= s)    t--;
    if(c > t)    return s - c;
    else    return sg(c, t);
}
int main(){
    for (int kase(1),n;scanf("%d",&n) && n && printf("Case %d:\n",kase++);){
        int si,ci,ans(0);
        while(n--){
            scanf("%d%d",&si,&ci);
            ans ^= sg(ci,si);
        }
        printf( ans ? "Yes\n" : "No\n");
    }
    return 0;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值