hdu3595 - 博弈论(every-sg游戏)

题目连接:http://acm.hdu.edu.cn/showproblem.php?pid=3595

题解参考:https://blog.csdn.net/u012139398/article/details/38000613

代码如下:

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<vector>
#include<cmath>
#include<set>
#include<string>
#include<cstring>
#define ll long long
using namespace std;
const int N=1005;
int sg[N][N],step[N][N];

int every_sg(int a,int b){
    if(sg[a][b]!=-1)return sg[a][b];
    if(a>b)swap(a,b);//a<b
    int ma=0,mi=0x3f3f3f3f;
    for(int i=a;i<=b;i+=a){
        if(every_sg(a,b-i)==0){//后继状态为先手必败,那该状态为先手必胜,求step的最大值
            ma=max(ma,step[a][b-i]);
            sg[a][b]=sg[b][a]=1;
        }
        else {
            mi=min(mi,step[a][b-i]);//否则求step最小值
        }
    }
    if(sg[a][b]==1){
        step[a][b]=step[b][a]=ma+1;
        return 1;
    }
    else{
        step[a][b]=step[b][a]=mi+1;
        return sg[a][b]=sg[b][a]=0;
    }
}

int main(){
    int n,a,b;
    memset(sg,-1,sizeof(sg));
    for(int i=0;i<N;i++){
        step[i][0]=step[0][i]=sg[i][0]=sg[0][i]=0;
    }
    while(scanf("%d",&n)!=EOF){
        int ans=0;
        while(n--){
            scanf("%d%d",&a,&b);
            every_sg(a,b);
            ans=max(ans,step[a][b]);
        }
        if(ans%2)printf("MM\n");
        else printf("GG\n");
    }
}

猜你喜欢

转载自blog.csdn.net/m0_37579232/article/details/82824944