HDOJ 1729 Stone Game

来源:互联网 发布:淘宝iphonese2000元 编辑:程序博客网 时间:2024/05/16 16:13

那么对于这些较难的博弈问题可以不断去找必败点,找出临界值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;

}

原创粉丝点击