zoukankan      html  css  js  c++  java
  • SGU 275 To xor or not to xor

    题目链接http://acm.sgu.ru/problem.php?contest=0&problem=275

    http://acm.hust.edu.cn/vjudge/contest/view.action?cid=98837#problem/A

    题目分类:高斯消元

    题意:给定n个数,从中选择任意个数,使它们的异或值最大

    题目分析:把每个数用二进制表示,要使异或值最大,要让高位尽量为1,用高斯消元判断高位是不是1

    1. 根据数的二进制表示,建立方程组的矩阵,结果那列置为1。
    2. 从下往上高斯消元(高位放下面),如果该行有未被控制的变元,则该行的结果一定为1,且该变元控制该行。
    3. 从该行往上依次消掉(异或)该变元。
    4. 如果该行没有可以用来控制的变元,如果最后一列是0,则该行结果也为1,否则该行结果为0。这里能抱着已用来控制的变元的系数全是0,因为在第3步时就消掉该行以上此列的0了,后面0与0以后还是0。所以如果最后一列是0, 即该行方程也可以成立,故结果为1。

    建立方程:

    a11x1+a21x2……=d[1]

    a12x1+a22x2……=d[2]

    ……

    代码:

    #include<bits/stdc++.h>
    
    using namespace std;
    
    #define INF 0x3f3f3f3f
    
    long long bit[100];
    int a[100][110];
    bool used[110];
    
    int main()
    {
        //freopen("in.txt","r",stdin);
        //freopen("out.txt","w",stdout);
        bit[0] = 1;
        for(int i = 1;i < 63;i++)
            bit[i] = 2*bit[i-1];
        int n;
        long long x;
        while(scanf("%d",&n) == 1)
        {
            for(int i = 0;i < n;i++)
            {
                cin>>x;
                for(int j = 0;j < 63;j++)
                {
                    if(x & bit[62-j])
                        a[j][i] = 1;
                    else a[j][i] = 0;
                }
            }
            for(int i = 0;i < 63;i++)
                a[i][n] = 1;
            memset(used,false,sizeof(used));
            long long ans = 0;
            for(int i = 0;i < 63;i++)
            {
                int x = -1;
                for(int j = 0;j < n;j++)
                    if(a[i][j] && !used[j])
                    {
                        x = j;
                        break;
                    }
                if(x == -1 && a[i][n] == 0)
                    ans += bit[62-i];
                else if(x != -1)
                {
                    ans += bit[62-i];
                    for(int k = i+1; k < 63;k++)
                        if(a[k][x])
                        {
                            for(int j = 0;j <= n;j++)
                                a[k][j] ^= a[i][j];
                        }
                }
            }
            cout<<ans<<endl;
        }
        return 0;
    }
    anytime you feel the pain.hey,refrain.don't carry the world upon your shoulders
  • 相关阅读:
    算法训练 P1103
    算法训练 表达式计算
    算法训练 表达式计算
    基础练习 时间转换
    基础练习 字符串对比
    Codeforces 527D Clique Problem
    Codeforces 527C Glass Carving
    Codeforces 527B Error Correct System
    Codeforces 527A Glass Carving
    Topcoder SRM 655 DIV1 250 CountryGroupHard
  • 原文地址:https://www.cnblogs.com/gaoss/p/4954935.html
Copyright © 2011-2022 走看看