hdu 3595 every-sg

every-sg的一些知识:

每一个能操作的游戏都要进行操作,谁不能继续操作了谁输。

所以对于一个必输的游戏,那么要尽快的输掉,对于必胜的游戏则要越慢的赢掉。

这里引用一下国家队的论文


https://wenku.baidu.com/view/7cd481e9524de518964b7d1f.html

所以建立一个sg保存胜负,根据上面求一下step即可。

即 若当前为必胜状态,取所有后继状态step的最大值+1;

若当前为必败状态,取所有后继状态step的最小值+1;

不要忘记初始化。

#include<bits/stdc++.h>

using namespace std;

const int maxn=1e3+5;

int sg[maxn][maxn];
int step[maxn][maxn];

int Step(int a,int b)
{
    if(sg[a][b]!=-1)
        return sg[a][b];
    if(a>b)
        swap(a,b);
    int M=-1,Min=0xfffffff;
    for(int i=a;i<=b;i+=a)
    {
        int t=Step(a,b-i);
        if(t==0)
        {
            M=max(M,step[a][b-i]);
            sg[a][b]=sg[b][a]=1;
        }
        else Min=min(Min,step[a][b-i]);
    }
    if(sg[a][b]==1)
        step[a][b]=step[b][a]=M+1;
    else
    {
        step[a][b]=step[b][a]=Min+1;
        sg[a][b]=sg[b][a]=0;
    }
    return sg[a][b];
}

int main()
{
    int n,m,x;
    int a,b;
    int T;
    while(cin>>n)
    {
        memset(sg,-1,sizeof(sg));
        int ans=-1;
        for(int i=0;i<maxn;i++)
            sg[i][0]=sg[0][i]=0,step[i][0]=step[0][i]=0;
        for(int i=0;i<n;i++)
        {
            cin>>a>>b;
            Step(a,b);
            ans=max(ans,step[a][b]);
        }
        if(ans%2)
            cout<<"MM"<<endl;
        else cout<<"GG"<<endl;
    }
    return 0;
}



猜你喜欢

转载自blog.csdn.net/numberer/article/details/79575918