• HDU 1809 A New Tetris Game(2)


    HDU_1809

        这个题目可以用SG函数求解。

        由于对于任意一个棋盘来讲,如果将棋盘的状态看成一个节点,那么这个游戏就相当于是在一个有向无环图上行走。

        而各个棋盘间是独立的,因此可以将每个棋盘的SG值先求出来,然后异或起来就得到了游戏整体的SG值。

    #include<stdio.h>
    #include<string.h>
    #define HASH 10007
    #define MAXD 10010
    #define MAXN 55
    typedef long long LL;
    int S, N, M, sg[MAXD], g[MAXN][MAXN];
    struct HashMap
    {
        int head[HASH], size, next[MAXD];
        LL st[MAXD];
        void init()
        {
            memset(head, -1, sizeof(head)), size = 0;
        }
        int find(LL _st)
        {
            int i, h = _st % HASH;
            for(i = head[h]; i != -1; i = next[i])
                if(st[i] == _st) break;
            return i;
        }
        void push(LL _st)
        {
            int h = _st % HASH;
            st[size] = _st, sg[size] = -1;
            next[size] = head[h], head[h] = size ++;
        }
    }hm;
    LL encode(int code[][MAXN])
    {
        int i, j;
        LL ans = 0;
        for(i = 0; i < N; i ++)
            for(j = 0; j < M; j ++) ans = ans << 1 | code[i][j];
        return ans;
    }
    void decode(int code[][MAXN], LL st)
    {
        int i, j;
        for(i = N - 1; i >= 0; i --)
            for(j = M - 1; j >= 0; j --) code[i][j] = st & 1, st >>= 1;    
    }
    void init()
    {
        char b[MAXN];
        int i, j;
        scanf("%d%d", &N, &M);
        for(i = 0; i < N; i ++)
        {
            scanf("%s", b);
            for(j = 0; j < M; j ++) g[i][j] = b[j] - '0';    
        }
    }
    int dfs(int cur, LL st)
    {
        int i, j, k, g[MAXN][MAXN], h[MAXN];
        decode(g, st);
        memset(h, 0, sizeof(h));
        for(i = 0; i < N - 1; i ++)
            for(j = 0; j < M - 1; j ++)
                if(!g[i][j] && !g[i + 1][j] && !g[i][j + 1] && !g[i + 1][j + 1])
                {
                    g[i][j] = g[i + 1][j] = g[i][j + 1] = g[i + 1][j + 1] = 1;
                    LL c = encode(g);
                    k = hm.find(c);
                    if(k != -1) h[sg[k]] = 1;
                    else
                    {
                        hm.push(c), k = hm.find(c);
                        h[dfs(k, c)] = 1;    
                    }
                    g[i][j] = g[i + 1][j] = g[i][j + 1] = g[i + 1][j + 1] = 0;
                }
        for(i = 0; h[i]; i ++);
        return sg[cur] = i;
    }
    void solve()
    {
        int i, j, k, ans = 0, t;
        for(t = 0; t < S; t ++)
        {
            init(), hm.init();
            LL c = encode(g);
            hm.push(c), k = hm.find(c);
            dfs(k, c);
            ans ^= sg[k];
        }
        printf("%s\n", ans ? "Yes" : "No");
    }
    int main()
    {
        while(scanf("%d", &S) == 1)
        {
            solve();    
        }
        return 0;    
    }

     

  • 相关阅读:
    Upgrading CentOS 6 to CentOS 7
    redis主从同步错误处理
    【linux】free命令中cached和buffers的区别
    服务器TIME_WAIT和CLOSE_WAIT区别及解决方案
    msyql 主从切换
    MySQL主从同步报错1507
    MYSQL SHOW 用法
    NGINX中的proxy_pass和rewrite
    Web服务器Nginx多方位优化策略
    operator重载运算符
  • 原文地址:https://www.cnblogs.com/staginner/p/2663834.html
Copyright © 2020-2023  润新知