HDU 6186 CS Course 位运算 思维

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

  题目描述: 给你n个数, q次查询, 问删除某个数后整体的与, 或, 异或值

  解题思路: ......纯码力, 讨论是不是唯一的0, 唯一的1, 1的奇偶就可以, 提前预处理每一列的1和0的个数之和, 但是码力也不是太好, 因为一个数异或两个相同的数等于没有异或, 所以只要最后异或一个a[i]就是异或的最后答案.......今天有点儿困了, 明天把我的代码Debug.....今天中午没睡.....

  代码: 自己写的代码WA掉了啊......不知道错在哪里, 按照网上题解的思路写.....他们对位运算的理解是真的透彻啊.....我也要记住这些技巧

      自己WA的代码:

#include <iostream>
#include <cstdio>
#include <string>
#include <vector>
#include <cstring>
#include <iterator>
#include <cmath>
#include <algorithm>
#include <stack>
#include <deque>
#include <map>
#define lson l, m, rt<<1
#define rson m+1, r, rt<<1|1
#define mem0(a) memset(a,0,sizeof(a))
#define sca(x) scanf("%d",&x)
#define de printf("=======\n")
typedef long long ll;
using namespace std;

const int maxn = 1e5+10;
int a[maxn][32];
int cnt1[32];
int cnt0[32];
int aa[32];
int oo[32];
int xx[32];

void turn(int row, int num) {
    int cnt = 0;
    while( num ) {
        a[row][cnt++] = num % 2;
        num /= 2;
    }
}

ll turnbacka() {
    ll ans = 0;
    for( int i = 0; i < 32; i++ ) {
        if( aa[i] == 1 ) {
            ans += pow(2, i);
        }
    }
    return ans;
}
ll turnbacko() {
    ll ans = 0;
    for( int i = 0; i < 32; i++ ) {
        if( oo[i] == 1 ) {
            ans += pow(2, i);
        }
    }
    return ans;
}
ll turnbackx() {
    ll ans = 0;
    for( int i = 0; i < 32; i++ ) {
        if( xx[i] == 1 ) {
            ans += pow(2, i);
        }
    }
    return ans;
}
const int temp = 1e5+10;
int x[temp];

int main() {
    int n, q;
    scanf( "%d%d", &n, &q );
    mem0(x), mem0(a), mem0(cnt1), mem0(cnt0);
    int tand = 0x3fffffff, tor = 0, txor = 0;
    for( int i = 0; i < n; i++ ) {
        int num;
        sca(num);
        
        tand = tand & num;
        tor = tor | num;
        txor = txor ^ num;

        turn(i, num);
    }
    
    for( int i = 0; i < 32; i++ ) {
        for( int j = 0; j < n; j++ ) {
            if( a[j][i] ) cnt1[i]++;
            else cnt0[i]++;
        }
    }
    for( int i = 0; i < q; i++ ) {
        sca(x[i]);
    }
    for( int j = 0; j < q; j++ ) {
        mem0(aa), mem0(oo), mem0(xx);
        for( int i = 0; i < 32; i++ ) {
            if( (a[x[j]-1][i] == 0 && cnt0[i] == 1) || cnt1[i] == n ) {
                aa[i] = 1;
            }
            else {
                aa[i] = 0;
            }
            if( (a[x[j]-1][i] == 1 && cnt1[i] == 1) || cnt0[i] == n ) {
                oo[i] = 0;
            }
            else {
                oo[i] = 1;
            }
            if( a[x[j]-1][i] == 1 && (cnt1[i]&1) ) {
                xx[i] = 0;
            }
            else if( a[x[j]-1][i] == 1 && !(cnt1[i]&1) ) {
                xx[i] = 1;
            }
            else if( a[x[j]-1][i] == 0 && (cnt1[i]&1) ) {
                xx[i] = 1;
            }
            else if( a[x[j]-1][i] == 0 && !(cnt1[i]&1) ) {
                xx[i] = 0;
            }
        }
        printf( "%lld ", turnbacka());
        printf( "%lld ", turnbacko());
        printf( "%lld\n", turnbackx());
    }
    return 0;
}
Wrong Answer

      按照网上的思路写的代码:

#include <iostream>
#include <cstdio>
#include <string>
#include <vector>
#include <cstring>
#include <iterator>
#include <cmath>
#include <algorithm>
#include <stack>
#include <deque>
#include <map>
#define lson l, m, rt<<1
#define rson m+1, r, rt<<1|1
#define mem0(a) memset(a,0,sizeof(a))
#define sca(x) scanf("%d",&x)
#define de printf("=======\n")
typedef long long ll;
using namespace std;

const int maxn = 1e6+5;
int n, m;
int aa, oo, xx;
int a[maxn], b[maxn];

int main() {
    while( ~scanf( "%d%d", &n, &m ) ) {
        mem0(b);
        xx = 0, aa = 0xffffffff, oo = 0;
        for( int i = 1; i <= n; i++ ) {
            int x;
            sca(x);
            a[i] = x;
            aa &= x, oo |= x, xx ^= x;
            for( int j = 0; x; j ++, x>>=1 ) {
                b[j] += x % 2;
            }
        }
        while( m-- ) {
            int q;
            sca(q);
            q = a[q];
            int A = aa;
            int O = oo;
            int X = xx;
            X = X ^ q;
            for( int j = 0; j <= 30; j++, q>>=1 ) {
                if( b[j] == n-1 && q%2==0 ) A += (1 << j);
                if( b[j] == 1 && q%2 ) O -= (1 << j);
            }
            printf( "%d %d %d\n", A, O, X);
        }
    }
}
View Code

  思考: 感谢作者 雪儿的期许 , 代码很优雅........自己对位运算真的是只知道最基础的啊.........感觉自己好弱啊..........

  然后自己入健身这个坑了啊.....只能晚上牺牲看美剧的时间了......养生养生......

 

posted on 2017-08-31 23:23  FriskyPuppy  阅读(193)  评论(0编辑  收藏  举报

导航