Hdu--5088(高斯消元)
2014-11-01 22:06:02
思路:考虑将每个数的二进制形式看成一行,形成一个矩形,然后高斯消元即可。为什么这么做呢?具体证明阐述不清,看具体样例就行:
5个数:1、2、3、4、5,形成的矩阵:(括号中表示原来的十进制数)
0 0 1 (1)
0 1 0 (2)
0 1 1 (3)
1 0 0 (4)
1 0 1 (5)
消元相当于:两数异或
结果:
1 0 0 (4)
0 0 1 (1)
0 0 0 (3)
0 1 0 (2)
0 0 0 (5)
发现最后有全0的情况,发现(5)的全0情况来自于:5 xor 4 xor 1 = 0,那么我们只要把2和3去掉,留下1、4、5即能满足要求。
发现(3)的全0情况来自于:3 xor 2 xor 1 = 0,那么我们只要把4和5去掉,留下1、2、3即能满足要求。
所以说只要在最后的矩阵里面找到一行全0的情况就是Yes,否则就是No。。(最后被Yes中的小写坑了,不应该啊QAQ)
1 /************************************************************************* 2 > File Name: 1003.cpp 3 > Author: Nature 4 > Mail: 564374850@qq.com 5 > Created Time: Sat 01 Nov 2014 09:46:10 PM CST 6 ************************************************************************/ 7 8 #include <cstdio> 9 #include <cstring> 10 #include <cstdlib> 11 #include <cmath> 12 #include <vector> 13 #include <map> 14 #include <set> 15 #include <stack> 16 #include <queue> 17 #include <iostream> 18 #include <algorithm> 19 using namespace std; 20 #define lp (p << 1) 21 #define rp (p << 1|1) 22 #define getmid(l,r) (l + (r - l) / 2) 23 #define MP(a,b) make_pair(a,b) 24 typedef long long ll; 25 const int INF = 1 << 30; 26 27 ll T,N; 28 ll a[1010]; 29 30 bool Gauss(){ 31 ll i,j,row = 0; 32 for(i = 0; i < 64; ++i){ 33 for(j = row; j < N; ++j) 34 if((a[j] >> i) & 1LL) break; 35 if(j < N){ 36 swap(a[row],a[j]); 37 for(ll k = row + 1; k < N; ++k) 38 if((a[k] >> i) & 1LL) a[k] ^= a[row]; 39 } 40 ++row; 41 } 42 for(i = 0; i < N; ++i) 43 if(!a[i]) return true; 44 return false; 45 } 46 47 int main(){ 48 scanf("%I64d",&T); 49 while(T--){ 50 scanf("%I64d",&N); 51 for(ll i = 0; i < N; ++i) 52 scanf("%I64d",&a[i]); 53 if(Gauss()) printf("Yes\n"); 54 else printf("No\n"); 55 } 56 return 0; 57 }