• Split Game (SG函数)


    题意:有n个堆,每个堆的高度为pi,两人玩游戏,每次可以任选一堆,并选择小于此堆的高度h(h<=pi)把这堆分离成高度为h的堆和高度为pi%h的堆。堆高为1时,是不可再分的。问:先手赢还是后手赢。

    题解:

    SG函数,我们先预处理前2000的SG函数。这里每次求SG值时,后继状态(一个堆分为多个堆)我们是异或的,不像之前的(一个堆就分为一个堆)就 直接标记下后继状态。为什么呢?

    之前状态转移是确定的,一堆转移后还是一堆(只是数量变了)可以直接确定转移后的SG函数值,现在是一堆转移成多堆,原来堆的sg函数就是分成各个自堆函数的异或和,这个可以根据SG定理可得:游戏和的SG函数等于各个游戏SG函数的Nim和,所以说把一个堆分成多个堆就是一个NIM游戏。后继状态就是各个子堆的异或和。

    #include<iostream>
    #include<cstring>
    #include<cmath>
    #include<algorithm>
    #include<cstdio>
    #include<vector>
    #include<map>
    #include<set>
    #include<queue>
    #include<stack>
    //#define _for(i,a,b) for(int i=a;i<=b;i++)
    using namespace std;
    typedef long long ll;
    double eps=0.05;
    ll mod=1e9+7;
    const int INF=0x3f3f3f3f,inf =0x3f3f3f3f;
    const int MAXN=2e3+10;
    const int maxn = 1e7+10;
    //ll inf=100000000000000;
    //template<typename T>inline void read(T &x)
    //{
    //    x=0;
    //    static int p;p=1;
    //    static char c;c=getchar();
    //    while(!isdigit(c)){if(c=='-')p=-1;c=getchar();}
    //    while(isdigit(c)) {x=(x<<1)+(x<<3)+(c-48);c=getchar();}
    //   x*=p;
    //}
    typedef unsigned long long ull;
    const int N=1e5+7;
    const double PI=acos(-1.0);
    int SG[2010];
    set<int> S;
    void init()
    {
        SG[1]=0;
        int tmp=0;
        for(int i=2;i<=2002;i++)
        {
           S.clear();
           for(int j=1;j<i;j++)
           {
               tmp=0;
               if((i/j)&1) tmp^=SG[j];//偶数异或和为0,奇数为本身
               if(i%j)
               tmp^=SG[i%j];
               S.insert(tmp);
    
           }
           for(int j=0;;j++)
           {
               if(!S.count(j)){
                SG[i]=j;break;
               }
           }
        }
    
    }
    int main()
    {
        init();
        int n;
        scanf("%d",&n);
        int item,sum=0;
        for(int i=1;i<=n;i++)
        {
            scanf("%d",&item);
            sum^=SG[item];
        }
        if(sum) puts("First");
        else puts("Second");
        return 0;
    }
    View Code
  • 相关阅读:
    mysql索引类型 normal, unique, full text
    16.信号量互斥编程
    15.信号通信编程
    14.有名管道通信
    13.无名管道通讯编程
    12.多进程程序的操作
    11.进程控制理论
    10.时间编程
    9. 库函数方式文件编程
    8.Linux文件编程
  • 原文地址:https://www.cnblogs.com/kayiko/p/13616557.html
Copyright © 2020-2023  润新知