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; }
按照网上的思路写的代码:
#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); } } }
思考: 感谢作者 雪儿的期许 , 代码很优雅........自己对位运算真的是只知道最基础的啊.........感觉自己好弱啊..........
然后自己入健身这个坑了啊.....只能晚上牺牲看美剧的时间了......养生养生......
posted on 2017-08-31 23:23 FriskyPuppy 阅读(193) 评论(0) 编辑 收藏 举报