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 }

 

  

posted @ 2014-11-01 22:43  Naturain  阅读(152)  评论(0编辑  收藏  举报