sgu 153


博弈游戏,一开始想搞 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
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值