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

SG处理 博弈

在 容量为 c ,现有数量为 s 的情况下

特殊情况: s==0 则 return 0; 否则:

找到一个整数 t  ,t 满足 t+t*t<c 而已 (t+1)+(t+1)*(t+1)>=c ,

这样的话 从 t+1 到 c-1 都为必胜态 而 s==c 时为必败态

只要 s 在 t+1 <= s <= c    它对应到S-Nim里面的 值就是 c-s

因为 这时的 s 可以到达 s-1,s-2,s-3,.......,c. 归纳一下的话 就是 c-s

但如果 s <= t 则递归 ( t , s ) 

递归是正确的  对应到 S-Nim 里的值为 k 的话 假设不正确 那么它应该可以经过一步到 上一层函数里的 k  ,显然不可能 所以它是正确的

代码:

#include<iostream>
#include<cstdio>
#include<cstring>
#include<string>
#include<vector>
#include<queue>
#include<map>
#include<stack>
#include<algorithm>
#include<cmath>

using namespace std;
//#pragma comment(linker,"/STACK:1000000000,1000000000")

#define LL long long

//const int INF=0x3f3f3f3f;
//const int N=1005;
int mex(int c,int s)
{
    if(s==0)
    return 0;
    int t=(int)(sqrt(1.0*c));
    while(t+t*t>=c)
    --t;
    if(s>t)
    return c-s;
    else
    return mex(t,s);
}
int main()
{
    //freopen("data.txt","r",stdin);
    int n;
    int ca=1;
    while(scanf("%d",&n)!=EOF,n)
    {
        int k=0;
        while(n--)
        {
            int c,s;
            cin>>c>>s;
            k=(k^mex(c,s));
        }
        cout<<"Case "<<(ca++)<<":"<<endl;
        if(k)
        cout<<"Yes"<<endl;
        else
        cout<<"No"<<endl;
    }
    return 0;
}

 

posted on 2012-10-16 20:41  夜->  阅读(175)  评论(0编辑  收藏  举报