一堆石子,编号从1-n,每次可以取1-k个编号连续的石子
求先手是否必胜
打表找规律即可
如下
#include <bits/stdc++.h> #define rep(ii,a,b) for(int ii=a;ii<=b;++ii) #define per(ii,a,b) for(int ii=b;ii>=a;--ii) #define show(x) cout<<#x<<"="<<x<<endl #define show2(x,y) cout<<#x<<"="<<x<<" "<<#y<<"="<<y<<endl #define show3(x,y,z) cout<<#x<<"="<<x<<" "<<#y<<"="<<y<<" "<<#z<<"="<<z<<endl #define show4(w,x,y,z) cout<<#w<<"="<<w<<" "<<#x<<"="<<x<<" "<<#y<<"="<<y<<" "<<#z<<"="<<z<<endl #define show5(v,w,x,y,z) cout<<#v<<"="<<v<<" "<<#w<<"="<<w<<" "<<#x<<"="<<x<<" "<<#y<<"="<<y<<" "<<#z<<"="<<z<<endl #define showa(x,a,b) cout<<#x<<": ";rep(i,a,b) cout<<x[i]<<' ';cout<<endl using namespace std;//head const int maxn=1e5+10,maxm=2e6+10; int casn,n,m,k,kase; int sg[maxn]; int getmex(bool vis[]){ int mex=0; while(vis[mex]) ++mex; return mex; } int getsg(int now,int k){ if(~sg[now]) return sg[now]; bool vis[now*100]={0}; rep(i,1,k){ rep(j,0,now-k){ vis[getsg(j,k)^getsg(now-(j+k),k)]=1; } } return sg[now]=getmex(vis); } int main(){ memset(sg,-1,sizeof sg); cin>>n>>k; sg[0]=0; rep(i,1,k) sg[i]=1; rep(i,1,n)getsg(i,k); showa(sg,1,n); }
k=1的时候,n为奇数先手必胜,否则先手必胜