• 51Nod1831 小C的游戏


    Problem

    小C和小L是好朋友,她们在玩一个游戏。
    一开始有一个大小为n的石子堆,小C先手。
    每次可以对这个石子堆拿走一个或者把这个石子堆分成等量的几份并只取其中一份(不能不变或只剩下一个)。
    如果取走最后一个人的算败,请问这个游戏小C是否能胜。

    Solution

    SG打表,总体上是质数败,但有几个不一样的。

    注意sg[1]=0,从sg[2]开始计算。

    不需要算奇偶个异或,题目的意思是取出一份来,用这一份继续游戏。

    最简单的做法就是找规律了,直接搜一下就能获得所有的胜负态。
    仔细观察可以发现质数除了2和17就是败的,合数除了16,34和289都是赢的。
    感觉这样是不太科学的,那就来讲讲道理。
    我们发现2,4,8都是赢的,而16的后继状态都是赢的,所以它是败的,而2^n(n>4)都能转化到16。
    同样的我们能说明17和2^n17^m。
    我们考虑一个合数,它的因数肯定有个败态的,它就必胜了。
    这样也就说明了质数是必败了。

    Code

    #include<stdio.h>
    #include<set>
    #include<iostream>
    #include<stack>
    #include<cstring>
    #include<cmath>
    #include<vector>
    #include<map>
    #include<queue>
    #include<algorithm>
    typedef long long ll;
    typedef long double ld;
    typedef double db;
    #define io_opt ios::sync_with_stdio(false);cin.tie(0);cout.tie(0)
    using namespace std;
    const int mod=1e9+7;
    inline int mo(ll a,int p){
        return a>=p?a%p:a;
    }
    inline int rd() {
        int x = 0, f = 1;
        char ch;
        while (ch < '0' || ch > '9') {
            if (ch == '-')f = -1;
            ch = getchar();
        }
        while (ch >= '0' && ch <= '9') {
            x = x * 10 + ch - '0';
            ch = getchar();
        }
        return f * x;
    }
    inline ll gcd(ll x, ll y){
        return y==0?x:gcd(y,x%y);
    }
    inline ll speed(ll a,ll b,int p){
        ll cur=a,anss=1;
        while(b){
            if(b&1) anss=anss*cur%p;
            cur=cur*cur%p;
            b>>=1;
        }
        return anss%p;
    }
    const int MAXN=1e5;
    bool ipr[MAXN+20];
    int cnt,pri[MAXN/5];
    void prime(){//埃式筛法
        int N=sqrt(MAXN)+0.5,mul;
        memset(ipr,true,sizeof(ipr));
        ipr[1]=false;
        for(int i=2;i<=N;i++){
            if(ipr[i]){
                i==2?mul=1:mul=2;
                for(int j=i*i;j<=MAXN;j+=i*mul){
                    ipr[j]=false;
                }
            }
        }
        for(int i=2;i<=MAXN;i++){
            if(ipr[i]){
                pri[++cnt]=i;
            }
        }
    }
    ll sg[100020];
    ll fg[10020];
    int gn1(ll x){
        int ret=0;
        while(x){
            ret++;
            x=x&(x-1);
        }
        return ret;
    }
    void dfs(int mx,int dep,int sum){
        if(dep==0){
            fg[sum]=1;
            return;
        }
        for(int i=0;i<=mx;i++){
            dfs(i,dep-1,sum^sg[i]);
        }
    }
    void getsg(int n=300){
        for(int i=2;i<=n;i++){
            memset(fg,0,sizeof(fg));
            fg[sg[i-1]]=1;
            for(int j=2;j<i;j++){
                if(i%j==0){
                    fg[sg[i/j]]=1;
                    /*if(j%2){
                        fg[sg[i/j]]=1;
                    }
                    else{
                        fg[0]=1;
                    }*/
                }
            }
            for(int j=0;;j++){
                if(!fg[j]){
                    sg[i]=j;
                    break;
                }
            }
        }
    }
    int n;
    bool fun(int x){
        if(x==1) return true;
        if(x<=MAXN) return ipr[x];
        for(int i=1;i<=cnt&&pri[i]*pri[i]<=x;i++){
            if(x%pri[i]==0) return false;
        }
        return true;
    }
    int main(){
        prime();
        int T;
        scanf("%d",&T);
        while(T--){
            scanf("%d",&n);
            if(n==0||n==16||n==34||n==289){
                printf("NIE
    ");
            }
            else if(n==2||n==17){
                printf("TAK
    ");
            }
            else if(fun(n)){
                printf("NIE
    ");
            }
            else{
                printf("TAK
    ");
            }
        }
        /*sg[1]=0;
        getsg();
        for(int i=1;i<=300;i++){
            if(sg[i]==0) cout<<i<<endl;
        }*/
        return 0;
    }
    
    
    
  • 相关阅读:
    PDO如何选择其他数据库的驱动
    PHP里关于时间日期大小写(Y,y,M,m...)
    数据库的基本操作
    数据库--PHP环境搭建
    曾经的中国互联网:多少巨头销声匿迹
    SQL 查找 45道练习题
    关于padding
    Mysql ERROR 1045 (28000): Access denied for user 'root'@'localhost'(using password: YSE)
    centos 格式化硬盘并挂载,添加重启后生效
    windows2003服务器不显示桌面怎么办
  • 原文地址:https://www.cnblogs.com/sz-wcc/p/13255729.html
Copyright © 2020-2023  润新知