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; }