sgu 153 分类: sgu templates 2015-04-26 16:35 32人阅读 评论(0) 收藏


博弈游戏,一开始想搞 sg 函数,结果搞不出。。。
然后发现序列状态很少,于是写了一个 Floyd 判圈算法找周期。


毕竟第一次写 Floyd判圈,wa了四次,好不容易才ac啊。。。



#include<map>
#include<stack>
#include<queue>
#include<ctime>
#include<cmath>
#include<string>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<utility>
#include<iostream>
#include<algorithm>
#define Mod(x) (((x)+MAXP)%MAXP)

const int MAXM = 12,MAXP = 12;

int k, n, m ,p[MAXM] = {0};

char str[2][30] = {"SECOND PLAYER MUST WIN","FIRST PLAYER MUST WIN"};

struct Status
{
    int s[MAXP],sp;

    void Trans()
    {
     s[Mod(++sp)] = 0;

     for(int j = 0; j <= m && !s[Mod(sp)]; j++)
       if(sp >= p[j]) s[Mod(sp)] = 1 ^ s[Mod(sp - p[j])];   
    }       
}st = {{1,0},0}, f ,g ;
bool equal(const Status &a,const Status &b)
{
    if(!(a.sp >= p[m] && b.sp >= p[m])) return false;

    for(int c = 0; c < p[m] ; c++)
       if(a.s[Mod(a.sp-c)]^b.s[Mod(b.sp-c)])
            return false;
    return true;        
}

int main()
{
#ifndef ONLINE_JUDGE
    freopen("sgu153.in","r",stdin);
    freopen("sgu153.out","w",stdout);
#endif

    std::cin >> k;

    while(k--)
    {
        memset(p,0,sizeof(p));

        std::cin >> n >> m;

        p[0] = 1;   
        for(int i = 1; i <= m; i++)
            std::cin >> p[i];
        std::sort(p ,p + m + 1);

        int T = 0, step;

        f = g = st;
        do{f.Trans(),g.Trans(),g.Trans(); }while(!equal(f,g));
        do{g.Trans(); T++; }while(!equal(f,g));

        if(n < f.sp) f = st, step = n;
        else   step = (n-f.sp)%T;

        for(int i = 1; i <= step; i++) f.Trans();

        std::cout << str[f.s[Mod(f.sp)]] << std::endl;
    }

#ifndef ONLINE_JUDGE
    fclose(stdin);
    fclose(stdout);
#endif
}

版权声明:本文为博主原创文章,未经博主允许不得转载。

posted @ 2015-04-26 16:35  <Dash>  阅读(161)  评论(0编辑  收藏  举报