首页 > 其他 > 详细

2018 南京区域赛A SG打表

时间:2019-10-11 19:23:08      阅读:81      评论:0      收藏:0      [点我收藏+]

一堆石子,编号从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为奇数先手必胜,否则先手必胜

 

2018 南京区域赛A SG打表

原文:https://www.cnblogs.com/nervendnig/p/11656124.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!