hdu 1536(博弈)

 

传送门:S-Nim

题意:给n个数的集合s, 再给m 组数据,每组表示 k 堆石子,每次可以取的个数只能是集合s中的数量。问先手胜还是输?

分析:sg函数的经典运用,先预处理出所有数量为0~10000的石子的sg值,然后判断k堆石子的sg值异或和是否为0来判断先手的输赢。

#include <cstdio>

#include <cstring>

#include <algorithm>

#define N 110

using namespace std;

int n,m,k;

int sg[N*N],a[N];

int dfs(int x)

{

    if(~sg[x])return sg[x];

    int vis[N],temp;

    memset(vis,0,sizeof(vis));

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

    {

        int temp=x-a[i];

        if(temp<0)break;

        temp=dfs(temp);

        vis[temp]=1;

    }

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

    {

        if(vis[i])continue;

        return sg[x]=i;

    }



}

int main()

{

    while(scanf("%d",&n),n)

    {

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

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

        {

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

        }

        sort(a,a+n);

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

            if(sg[i]==-1)dfs(i);

        scanf("%d",&m);

        while(m--)

        {

            scanf("%d",&k);

            int x,ans=0;

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

            {

                scanf("%d",&x);

                ans^=sg[x];

            }

            if(ans)printf("W");

            else printf("L");

            if(!m)puts("");

        }



    }

}
View Code

 

你可能感兴趣的:(HDU)