找出n个数中出现了奇数次的两个数

如果是找只出现了奇数次的一个数, 那么我们从头异或一遍就可以。 那么如何找出现了奇数次的两个数呢?

首先我们还是从头异或一遍, 然后结果肯定不为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\n", ans1, ans2);
44     }
45     return 0;
46 }

 

posted on 2015-12-21 10:33  yohaha  阅读(1053)  评论(0编辑  收藏  举报

导航