S-Nim 1536 HDU game function sg

S-Nim 1536 HDU game function sg

The meaning of problems

First inputs K, represents the size of a set, after the input set, which means that for the stone only to the number of elements in a set, then m represents an input to the next set to be m times that inquiry, after m rows , n represents a per line there are n piles, each pile there is a stone n1, asked the state represented by the line win or lose, if you win input W or L.

Problem-solving ideas

If the limit number is not time to take stones, then only necessary to stack the number of stones per XORed to, if the result is not 1, then the upper hand win, then the anti-winning hand.

But here each taking the number of stones has been restricted, you can only choose from several numbers, it is the need to process the SG function. As to why the SG did not write function to process here, reference may be made in this blog game theory SG function

Here we are just wrote a two way function SG: 1 is playing table method, 2 DFS law.

Code

//打表法实现
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int maxn=1e4+7;
int sg[maxn];
bool book[maxn];//这个需要用bool类型,如果改成int类型会超时,第一次遇到。
int s[107];
int k, m, l;
void getsg(int n, int k)//n代表这堆石子最多有多少,k代表有多少种取的模式
{
    int i, j;
    memset(sg, 0, sizeof(sg));
    for(i=1; i<=n; i++)
    {
        memset(book, 0, sizeof(book));//每次有需要进行
        for(j=1; j<=k && s[j]<=i; j++)
            book[sg[i-s[j]]]=1;
        for(j=0; ; j++)//查找里面第一个是0的
            if(!book[j])
            {
                sg[i]=j;
                break;
            }
    }
}
int main()
{
    while(scanf("%d",&k) && k)
    {
        for(int i=1; i<=k; i++)
            scanf("%d",&s[i]);
        sort(s+1, s+1+k);
        getsg(maxn-7, k);
        scanf("%d",&m);
        while(m--)
        {
            scanf("%d", &l);
            int tmp, ans=0;
            while(l--)
            {
                scanf("%d", &tmp);
                ans^=sg[tmp];
            }
            if(ans==0)
                printf("L");
            else
                printf("W"); 
        }
        printf("\n");
    }
    return 0;
}
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int maxn=10050+7;
int s[105];
int SG[maxn];
bool book[105];
int k, m, l;
int sg(int x)
{
    if(SG[x]!=-1) return SG[x];//记忆化搜索
    memset(book, 0, sizeof(book));
    for(int i=1; i<=k && x-s[i]>=0; i++)
        book[sg(x-s[i])]=1; //寻找他的下面的所有状态
    for(int i=0; i<105; i++) //找到第一个是0的位置
        if(book[i]==0) return SG[x]=i;
}

int main()
{
    while(scanf("%d", &k) && k)
    {
        for(int i=1; i<=k; i++)
            scanf("%d", &s[i]);
        sort(s+1, s+1+k);
        memset(SG, -1, sizeof(SG));
        scanf("%d",&m);
        while(m--)
        {
            scanf("%d", &l);
            int tmp, ans=0;
            for(int i=1;i<=l; i++)
            {
                scanf("%d", &tmp);
                ans^=sg(tmp);
            }
            if(ans==0) printf("L");
            else printf("W");
        }
        printf("\n");
    }
    return 0;
 } 

Guess you like

Origin www.cnblogs.com/alking1001/p/11704461.html