Codeforces Round #366 (Div. 2) B. Spider Man (组合游戏)

来源:互联网 发布:网络女作家 编辑:程序博客网 时间:2024/04/29 13:19

题目链接

有一个2个人玩的游戏,有n个圆环,每次的操作是选择一个大小不小于2的圆环,把它分成x,N-x(1<=x < N)2个子圆环。

换句话说,就是给你n堆石子,然后每次选择大小不小于2的分成2个小堆,且每堆大小大于0,不能操作的输。

题目问的是,给出n堆,n个询问,选择前i堆作为游戏开始,先手赢还是后手赢。

先用sg函数,打表计算下规律,打表的规律是奇数是0,偶数是1
然后直接异或就好了

#include<bits/stdc++.h>using namespace std;#define cl(a,b) memset(a,b,sizeof(a))#define LL long long#define pb push_back#define gcd __gcd#define For(i,j,k) for(int i=(j);i<k;i++)#define lowbit(i) (i&(-i))#define _(x) printf("%d\n",x)const int maxn = 1e6+10;const int inf  = 1 << 28;set<int> s;int sg[maxn];int grundy(int k){    s.clear();    sg[1]=0;   // s.insert(sg[1]);    for(int i=1;i<k;i++){        s.insert(sg[i]^(sg[k-i]));    }    int ans = 0;    while(s.count(ans))ans++;    sg[k]=ans;    return ans;}int sg_(int x){    if(x%2==0)return 1;    else return 0;}int main(){   /* for(int i=1;i<=25;i++){        printf("%2d ",i);    }    cout<<endl;    for(int i=1;i<=25;i++){        printf("%2d ",grundy(i));    }    cout<<endl;*/    int n;scanf("%d",&n);    LL ans = 0;    for(int i=0;i<n;i++){        LL x;scanf("%lld",&x);        ans^=sg_(x);       // cout<<"ans = "<<ans<<endl;        printf("%s\n",ans?"1":"2");    }    return 0;}
0 0
原创粉丝点击