zoukankan      html  css  js  c++  java
  • ACM学习历程—HDU 3915 Game(Nim博弈 && xor高斯消元)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3915

    题目大意是给了n个堆,然后去掉一些堆,使得先手变成必败局势。

    首先这是个Nim博弈,必败局势是所有xor和为0.

    那么自然变成了n个数里面取出一些数,使得xor和为0,求取法数。

    首先由xor高斯消元得到一组向量基,但是这些向量基是无法表示0的。

    所以要表示0,必须有若干0来表示,所以n-row就是消元结束后0的个数,那么2^(n-row)就是能组成0的种数。

    n==row特判一下。

    代码:

    #include <iostream>
    #include <cstdio>
    #include <cstdlib>
    #include <cmath>
    #include <cstring>
    #include <algorithm>
    #include <set>
    #include <map>
    #include <queue>
    #include <string>
    #define LL long long
    
    using namespace std;
    
    const int maxN = 105;
    const int MOD = 1000007;
    int n, s[maxN];
    
    void input()
    {
        scanf("%d", &n);
        for (int i = 0; i < n; ++i)
            scanf("%d", &s[i]);
    }
    
    //xor高斯消元求线性基
    //时间复杂度O(30n)
    int xorGauss(int n)
    {
        int row = 0;
        for (int i = 30; i >= 0; i--)
        {
            int j;
            for (j = row; j < n; j++)
                if(s[j]&(1<<i))
                    break;
            if (j != n)
            {
                swap(s[row], s[j]);
                for (j = 0; j < n; j++)
                {
                    if(j == row) continue;
                    if(s[j]&(1<<i))
                        s[j] ^= s[row];
                }
                row++;
            }
        }
        return row;
    }
    
    void work()
    {
        int row, ans, k;
        row = xorGauss(n);
        ans = n-row;
        if (ans != -1)
        {
            k = 1;
            while (ans)
            {
                k <<= 1;
                k %= MOD;
                ans--;
            }
            ans = k;
        }
        else
            ans = -1;
        printf("%d
    ", ans);
    }
    
    int main()
    {
        //freopen("test.in", "r", stdin);
        int T;
        scanf("%d", &T);
        for (int times = 0; times < T; ++times)
        {
            input();
            work();
        }
        return 0;
    }
    View Code
  • 相关阅读:
    Oracle启动关闭
    Open_stack 有虚拟机端口不通的问题
    关于Oracle归档的一些操作
    电脑无法开机 接通电源后主板有红灯闪烁的问题
    Centos7+python3.6+face-recognition
    电脑无法开机的问题-主板上有红色告警灯闪烁
    关于systemctl
    Vsftp搭建 for centos7
    外星人入侵——安装Pygame
    mysql索引原理详解
  • 原文地址:https://www.cnblogs.com/andyqsmart/p/4970095.html
Copyright © 2011-2022 走看看