hdu 1536 S-Nim

http://acm.hdu.edu.cn/showproblem.php?pid=1536

S-Nim 博弈 需要用SG 处理

最简单的S-Nim博弈是 每一堆可以任取正整数个 比如说 k 可以变成 k-1,k-2,k-3,······0

本题所可以取的数量有了限制 所以要SG处理 把原始数量可以对应到 S-Nim 里面的数量 是多对一的关系

如果原始数量n取过之后可以变成 S-Nim 里面的0,1,2,3,4,····· k-1 而没有 k 的话 那么n就对应到 S-Nim里面的 k

然后就变成最初的S-Nim了

代码:

#include<iostream>

#include<cstdio>

#include<cstring>

#include<string>

#include<vector>

#include<queue>

#include<map>

#include<stack>

#include<algorithm>



using namespace std;

//#pragma comment(linker,"/STACK:1000000000,1000000000")



#define LL long long



const int INF=0x3f3f3f3f;

const int N=105;

const int M=10005;

int choose[N];

int k[M];

int n;

int dp(int x)

{

    if(k[x]!=-1)

    return k[x];

    int visited[N];

    memset(visited,false,sizeof(visited));

    for(int i=0;i<n;++i)

    {

        if(x-choose[i]<0)

        break;

        visited[dp(x-choose[i])]=true;

    }

    for(int i=0;i<=n;++i)

    if(visited[i]==false)

    {k[x]=i;break;}

    return k[x];

}

int main()

{

    //freopen("data.txt","r",stdin);



    while(scanf("%d",&n)!=EOF,n)

    {

        for(int i=0;i<n;++i)

        scanf("%d",&choose[i]);

        sort(choose,choose+n);

        memset(k,-1,sizeof(k));

        int m;

        scanf("%d",&m);

        while(m--)

        {

            int l;

            scanf("%d",&l);

            int w=0;

            while(l--)

            {

                int tmp;

                scanf("%d",&tmp);

                w=(w^dp(tmp));

            }

            if(w)

            printf("W");

            else

            printf("L");

        }

        printf("\n");

    }

    return 0;

}

 

 

你可能感兴趣的:(HDU)