如果是找只出现了奇数次的一个数, 那么我们从头异或一遍就可以。 那么如何找出现了奇数次的两个数呢?
首先我们还是从头异或一遍, 然后结果肯定不为0, 对于异或出来的结果, 如果这个数的某一位是1, 说明出现了奇数次的那两个数在这一位上一个为0, 一个为1。 所以我们可以根据这个条件将原数组分为两个数组分别异或。
1 #include<bits/stdc++.h> 2 using namespace std; 3 #define pb(x) push_back(x) 4 #define ll long long 5 #define mk(x, y) make_pair(x, y) 6 #define lson l, m, rt<<1 7 #define mem(a) memset(a, 0, sizeof(a)) 8 #define rson m+1, r, rt<<1|1 9 #define mem1(a) memset(a, -1, sizeof(a)) 10 #define mem2(a) memset(a, 0x3f, sizeof(a)) 11 #define rep(i, a, n) for(int i = a; i<n; i++) 12 #define ull unsigned long long 13 typedef pair<int, int> pll; 14 const double PI = acos(-1.0); 15 const double eps = 1e-8; 16 const int mod = 1e9+7; 17 const int inf = 1061109567; 18 const int dir[][2] = { {-1, 0}, {1, 0}, {0, -1}, {0, 1} }; 19 int a[1000005]; 20 int main() 21 { 22 int n; 23 while(~scanf("%d", &n)) { 24 int tmp = 0; 25 for(int i = 0; i<n; i++) { 26 scanf("%d", &a[i]); 27 tmp^=a[i]; 28 } 29 int pos = -1; 30 for(int i = 0; ; i++) { 31 if(tmp&(1<<i)) { 32 pos = i; 33 break; 34 } 35 } 36 int ans1 = 0, ans2 = 0; 37 for(int i = 0; i<n; i++) { 38 if(a[i]&(1<<pos)) 39 ans1^=a[i]; 40 else 41 ans2^=a[i]; 42 } 43 printf("%d %d ", ans1, ans2); 44 } 45 return 0; 46 }