• HDU 1536 SNim


    HDU_1536

        比较直观的思路将每一堆的sg函数计算出来,然后看所有的sg函数异或之后是否为0。但实际上我们没必要每一堆都独立计算一遍sg函数,因为游戏规则是一样的,所以sg函数也必然是一样,所以只用开一个一维的sg[]数组记录sg函数的值即可。

        此外,一开始调用一下类似dp(10000)的递归函数企图预处理出sg[]的所有值的想法是错误的,因为假定初始石子是10000个的话,有些情况是可能取不到的,比如样例1,假定初始石子是10000个的话对于9999个石子的情况就没法取到。所以一个比较好的方式就是采用记忆化搜索的形式,用哪个就搜哪个。

        用于记录后继结点sg函数值的数组最好开成静态的放在递归函数外面,这样能节省一些时间。

    #include<stdio.h>
    #include<string.h>
    #define MAXS 110
    #define MAXD 10010
    int K, M, N, sg[MAXD], s[MAXS], h[MAXD][MAXS];
    int dfs(int n)
    {
    int i, j, k;
    if(sg[n] != -1)
    return sg[n];
    for(i = 0; i < K; i ++)
    if(n - s[i] >= 0)
    h[n][dfs(n - s[i])] = 1;
    for(i = 0; h[n][i]; i ++);
    return sg[n] = i;
    }
    void init()
    {
    int i, j, k;
    for(i = 0; i < K; i ++)
    scanf("%d", &s[i]);
    memset(sg, -1, sizeof(sg));
    memset(h, 0, sizeof(h));
    }
    void solve()
    {
    int i, j, k, ans;
    scanf("%d", &M);
    for(i = 0; i < M; i ++)
    {
    scanf("%d", &N);
    ans = 0;
    for(j = 0; j < N; j ++)
    {
    scanf("%d", &k);
    ans ^= dfs(k);
    }
    printf("%c", ans == 0 ? 'L' : 'W');
    }
    printf("\n");
    }
    int main()
    {
    for(;;)
    {
    scanf("%d", &K);
    if(!K)
    break;
    init();
    solve();
    }
    return 0;
    }


  • 相关阅读:
    Redis
    Redis入门
    C#编程--语句(分支语句)
    C#编程--运算符
    C#编程--输入和输出
    C#编程进制转换
    C#语言课程11月10日
    C#语言课程11月9日
    C#语言课程11月7日
    C#语言课程11月6日
  • 原文地址:https://www.cnblogs.com/staginner/p/2366406.html
Copyright © 2020-2023  润新知