HDOJ 1729 Stone Game

那么对于这些较难的博弈问题可以不断去找必败点,找出临界值SG

比如对于HDOJ 1729 Stone Game一题

http://acm.hdu.edu.cn/showproblem.php?pid=1729

我们可以设有一个箱子容量为s,d是一个必败点

达到d这点的话,我们可以达到的点为 d+1 ~ d+d*d

所以一定是: d+d*d < s

为了找出临界值,于是我的设我一步走到d+1

那么一定有: (d+1)*(d+1) + d+1 >= s

 

OK,话说到这里,我们由临界值得到了两个公式:

d + d*d < s --> d(d+1) < s

(d+1)*(d+1) + d+1 >= s --> (d+1)(d+2) >= s

那么我们由这两个公式

可以求出 s 的必败点 d

接下来要做的便是把d当作s去找它的必败点,直到找不下去

 

那么c 是起始的点数

我只要找到大于c的最小必败点

然后对每(d-c)异或,可以把

特例: c=s,c=0 必败点

AC CODE:

#include <iostream>

#include <cmath>

using namespace std;

int sg(int s, int c)

{

       int t = (int)sqrt(double(s));

       while (t*t+t >= s)

       {

              --t;

       } // 找到符和条件的点

       if (c > t) //找到大于c的最小必败点

              return s - c;

       else

              return sg(t, c);

}

int main()

{

       int i,j,k,n,m,t;

       int s,c,d;

       int cnt = 0;

       while (scanf("%d",&n)!=EOF,n)

       {

              cnt++;

              int ans = 0;

              for (i=0;i<n;i++)

              {

                     scanf("%d %d",&s,&c);

                     ans ^= sg(s,c);

              }

              if (!ans)   printf("Case %d:/nNo/n",cnt);

              else  printf("Case %d:/nYes/n",cnt);

       }

       return 0;

}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值