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;
}
浙公网安备 33010602011771号