zoukankan      html  css  js  c++  java
  • hdu 1536 S-Nim(sg函数模板)

    转载自:http://blog.csdn.net/sr_19930829/article/details/23446173

    解题思路:

    这个题折腾了两三天,参考了两个模板,在这之间折腾过来折腾过去,终于把用法和需要注意的地方弄清楚了,汗。注意的是: bool类型的数组比int类型的数组快,不超时与超时的区别,在sg组合博弈时,只能在(a1,a2,a3,a4)中取,要特别注意这里面的数字是否是有序的,这个特别重要,下面贴出的两个模板对应了两种情况。最后,大数据输入还得用scanf。。

    模板1(该模板注意的是一定要把 f 数组中的数字从小到大排序):

    const int N=10008;//N为所有堆最多石子的数量  
    int f[108],sg[N];//f[]用来保存只能拿多少个,sg[]来保存SG值  
    bool hash[N];//mex{}  
    void sg_solve(int t,int N)//t指f[]中的个数  
    {  
        int i,j;  
        memset(sg,0,sizeof(sg));  
        for(i=1;i<=N;i++)  
        {  
            memset(hash,0,sizeof(hash));  
            for(j=1;j<=t&&f[j]<=i;j++)  
            {  
                hash[sg[i-f[j]]]=1;  
            }  
            for(j=0;j<=N;j++)  
                if(!hash[j])  
                    break;  
            sg[i] = j;  
        }  
    }  

    模板2(该模板不需要进行排序)

    const int N=10008;//N为所有堆最多石子的数量  
    int f[108],sg[N];//f[]用来保存只能拿多少个,sg[]来保存SG值  
    bool hash[N];//mex{}  
    void sg_solve(int t,int N)  
    {  
        int i,j;  
        memset(sg,0,sizeof(sg));  
        for(i=1;i<=N;i++)  
        {  
            memset(hash,0,sizeof(hash));  
            for(j=1;j<=t;j++)  
                if(i - f[j] >= 0)  
                   hash[sg[i-f[j]]] = 1;  
            for(j=0;j<=N;j++)  
                if(!hash[j])  
                    break;  
            sg[i] = j;  
        }  
    }  

    代码(使用第二个模板)

    #include <iostream>  
    #include <algorithm>  
    #include <stdio.h>  
    #include <string.h>  
    using namespace std;  
      
    const int N=10008;//N为所有堆最多石子的数量  
    int f[108],sg[N];//f[]用来保存只能拿多少个,sg[]来保存SG值  
    bool hash[N];//mex{}  
    void sg_solve(int t,int N)  
    {  
        int i,j;  
        memset(sg,0,sizeof(sg));  
        for(i=1;i<=N;i++)  
        {  
            memset(hash,0,sizeof(hash));  
            for(j=1;j<=t;j++)  
                if(i - f[j] >= 0)  
                   hash[sg[i-f[j]]] = 1;  
            for(j=0;j<=N;j++)  
                if(!hash[j])  
                    break;  
            sg[i] = j;  
        }  
    }  
      
      
    int main()  
    {  
        int k,m,l,num,i,j;  
        while(scanf("%d",&k),k)  
        {  
            for(i=1;i<=k;i++)  
                scanf("%d",&f[i]);  
            sg_solve(k,N);  
            scanf("%d",&m);  
            string ans="";  
            for( i=1;i<=m;i++)  
            {  
                int sum=0;  
                scanf("%d",&l);  
                for( j=1;j<=l;j++)  
                {  
                    scanf("%d",&num);  
                    sum^=sg[num];  
                }  
                if(sum==0)  
                    ans+="L";  
                else  
                    ans+="W";  
            }  
            cout<<ans<<endl;  
        }  
        return 0;  
    }  
  • 相关阅读:
    fiddler无法抓取360浏览器包的问题
    腾讯云服务器上发送邮件连接超时(无法发送)的相关问题
    jQuery获取后台动态添加上去的选择器
    NOIP 模拟 $84; m 宝藏$
    NOIP 模拟 $83; m 铺设道路$
    NOIP 模拟 $83; m 传统艺能$
    NOIP 模拟 $83; m 时代的眼泪$
    NOIP 模拟 $83; m 树上的数$
    NOIP 模拟 $80; m 百鸽笼$
    NOIP 模拟 $80; m 滑稽树下你和我$
  • 原文地址:https://www.cnblogs.com/s1124yy/p/5712948.html
Copyright © 2011-2022 走看看