• HDU 1536 & 1944


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

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

    一样的题

    题意:先给一个集合,代表可能发生的转移。然后m个询问,可以理解为每次给l堆石子,每堆有hi个,问博弈策略

    直接用sg定理,非常简单,转移给的清清楚楚,照着写就行,递推或者记忆化搜索都行。

    这题的时间卡的紧,开始死活过不了,看别人代码把vis数组开成100就过了(原来开的1w),深感此题有问题,sg的值最大应该1w才对(或者我想错了欢迎指出?)

    AC 代码

    #include <iostream>
    #include <cstdio>
    #include <cstring>
    #include <set>
    #include <algorithm>
    
    using namespace std;
    
    int sg[10005], vis[105], s[105], k;
    
    void getSG() {
        sg[0] = 0;
        for(int j = 1; j <= 10000; j++) {
            memset(vis, 0, sizeof(vis));
            for(int i = 0; i < k; i++) {
                if(s[i] <= j) vis[sg[j-s[i]]] = 1;
            }
            for(int i = 0; ; i++) {
                if(!vis[i]) {
                    sg[j] = i;
                    break;
                }
            }
        }
    }
    
    int main() {
        while(~scanf("%d", &k), k) {
            for(int i = 0; i < k; i++)
                scanf("%d", &s[i]);
            getSG();
            int m;
            scanf("%d", &m);
            while(m--) {
                int l;
                scanf("%d", &l);
                int ans = 0;
                while(l--) {
                    int h;
                    scanf("%d", &h);
                    ans ^= sg[h];
                }
                if(!ans) putchar('L');
                else putchar('W');
            }
            putchar('
    ');
        }
        return 0;
    } 
    View Code
    #include <iostream>
    #include <cstdio>
    #include <cstring>
    #include <set>
    #include <algorithm>
    
    using namespace std;
    
    int sg[10005], vis[105], s[105], k;
    
    int getSG(int x) {
        if(sg[x] != -1) return sg[x]; 
        memset(vis, 0, sizeof(vis));
        for(int i = 0; i < k; i++) {
            if(s[i] <= x) {
                getSG(x-s[i]);
                vis[sg[x-s[i]]] = 1;
            }
        }
        for(int i = 0; ; i++) {
            if(!vis[i]) return sg[x] = i;
        }
    }
    
    int main() {
        while(~scanf("%d", &k), k) {
            for(int i = 0; i < k; i++)
                scanf("%d", &s[i]);
            int m;
            scanf("%d", &m);
            memset(sg, -1, sizeof(sg));
            sg[0] = 0;
            for(int i = 0; i <= 10000; i++)
                getSG(i);
            while(m--) {
                int l;
                scanf("%d", &l);
                int ans = 0;
                while(l--) {
                    int h;
                    scanf("%d", &h);
                    ans ^= sg[h];
                }
                if(!ans) putchar('L');
                else putchar('W');
            }
            putchar('
    ');
        }
        return 0;
    } 
    View Code

    超时代码(但感觉非常正确,不知道被卡在哪里)

    #include <iostream>
    #include <cstdio>
    #include <cstring>
    #include <set>
    #include <algorithm>
    
    using namespace std;
    
    int sg[10005], s[105], k;
    
    void getSG() {
        sg[0] = 0;
        for(int j = 1; j <= 10000; j++) {
            set <int> S;
            for(int i = 0; i < k; i++) {
                if(s[i] <= j) S.insert(sg[j-s[i]]);
            }
            int g = 0;
            while(S.count(g)) g++;
            sg[j] = g; 
        }
    }
    
    int main() {
        while(~scanf("%d", &k), k) {
            for(int i = 0; i < k; i++)
                scanf("%d", &s[i]);
            getSG();
            int m;
            scanf("%d", &m);
            while(m--) {
                int l;
                scanf("%d", &l);
                int ans = 0;
                while(l--) {
                    int h;
                    scanf("%d", &h);
                    ans ^= sg[h];
                }
                if(!ans) putchar('L');
                else putchar('W');
            }
            putchar('
    ');
        }
        return 0;
    } 
    View Code
    #include <iostream>
    #include <cstdio>
    #include <cstring>
    #include <set>
    #include <algorithm>
    
    using namespace std;
    
    int sg[10005], s[105], k;
    
    int getSG(int x) {
        if(sg[x] != -1) return sg[x]; 
        set <int> S;
        for(int i = 0; i < k; i++) {
            if(s[i] <= x) {
                S.insert(getSG(x-s[i]));
            }
        }
        int g = 0;
        while(S.count(g)) g++;
        return sg[x] = g;
    }
    
    int main() {
        while(~scanf("%d", &k), k) {
            for(int i = 0; i < k; i++)
                scanf("%d", &s[i]);
            int m;
            scanf("%d", &m);
            memset(sg, -1, sizeof(sg));
            sg[0] = 0;
            for(int i = 0; i <= 10000; i++)
                getSG(i);
            while(m--) {
                int l;
                scanf("%d", &l);
                int ans = 0;
                while(l--) {
                    int h;
                    scanf("%d", &h);
                    ans ^= sg[h];
                }
                if(!ans) putchar('L');
                else putchar('W');
            }
            putchar('
    ');
        }
        return 0;
    } 
    View Code
  • 相关阅读:
    数据分析之可反复与独立样本的T-Test分析
    朗朗上口的两幅对联
    mysql编码、数据表编码查看和改动总结
    2014-04-19编程之美初赛题目及答案解析
    测试集群模式安装实施Hadoop
    笔记:常用排序算法
    笔记:常用排序算法
    安装Redis并测试
    常见架构风格举例总结
    转载:PostgreSQL SQL的性能提升
  • 原文地址:https://www.cnblogs.com/xiaohongmao/p/4567836.html
Copyright © 2020-2023  润新知