hdu 1536

一道基础博弈sg题,据说要用递归调用sg函数,我用了比较笨的的方法,毕竟这是我第一道博弈 sg题,先练一下基础哈:

 

 

#include<iostream>
#include<stdio.h>
#include<algorithm>
using namespace std;
int move[101];
int sg[10001];
int vis[10001];
int main()
{
    //freopen("out","w",stdout);
    int n_move;
    while(scanf("%d",&n_move),n_move)
    {
        int i,j;
        memset(sg,-1,sizeof(sg));
        for(i=0;i<n_move;i++)
            scanf("%d",&move[i]);
        sg[0]=0;
        sort(move,move+n_move);
        for(i=1;i<10001;i++)
        {
            memset(vis,-1,sizeof(vis));
            int j;
            for(j=0;j<n_move&&move[j]<=i;j++)
                vis[sg[i-move[j]]]=0;
            for(j=0;;j++)
                if(vis[j]==-1)
                {
                    sg[i]=j;
                    break;
                }
        }
        int n;
        scanf("%d",&n);
        for(i=0;i<n;i++)
        {
            int nn,m;
            scanf("%d",&nn);
            for(j=0;j<nn;j++)
            {
                int a;
                scanf("%d",&a);
                if(j==0)
                   m=sg[a];
                else
                   m^=sg[a];
            }
            if(m==0)
                printf("L");
            else
                printf("W");
        }
        printf("\n");
    }
}

 

不过上面的代码由于效率太低通不过,下面是改进版本(好吧我承认我是看到题解才想到用递归)


#include<iostream>

#include<stdio.h>

using namespace std;

int move[101];

int sg[10001];

int n_move;

int getsg(int a)

{

if(sg[a]!=-1)

return sg[a];

 if(a-move[0]<0)

return sg[a]=0;

 int hand[100],i;

 memset(hand,0,sizeof(hand));

 for(i=0;i<n_move&&move[i]<=a;i++)

 hand[getsg(a-move[i])]=1;

 for(i=0;;i++)

if(hand[i]==0)

return sg[a]=i;}

int main()

{

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

 {

 int i,j;

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

sg[0]=0; for(i=0;i<n_move;i++)

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

 sort(move,move+n_move);

 int n_case;

 scanf("%d",&n_case);

 for(i=0;i<n_case;i++)

{ int n,m; scanf("%d",&n);

 for(j=0;j<n;j++)

 {

int a; scanf("%d",&a);

 if(j==0) m=getsg(a);

 else m^=getsg(a);

 }

 //cout<<sg[5]<<" "<<sg[12]<<endl;

 if(m==0)

printf("L");

 else printf("W");

 }

 printf("\n");

 }

}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值