1. 程式人生 > >Problem H: 《為什麼會變成這樣呢》(位運算)

Problem H: 《為什麼會變成這樣呢》(位運算)

Problem H: 《為什麼會變成這樣呢》

Description

“第一次有了喜歡的人,還得到了一生的摯友,兩份喜悅互相重疊,這雙重的喜悅又帶來了更多更多的喜悅,本應已經得到了夢幻一般的幸福時光,然而,為什麼,會變成這樣呢?”雙重的喜悅感卻無法帶來更多的幸福,現在,雪菜在很多喜悅感之中只想要得到兩份不重疊的喜悅感(其他的喜悅感都是重疊的),你能幫她找出這兩份不同的喜悅感是多少嗎?

Input

第一行一個整數T,代表資料的組數(1<=T<=10),接下來T組資料,每組資料的第一行是一個整數n(1<=n<=1000000),第二行是n個整數ai(0 <= ai <= 1000000000)代表喜悅感,每兩個整數之間有一個空格,題目保證有且僅有兩個不同的整數出現一次,其他的整數都是出現兩次。

Output

對於每組資料,輸出兩個整數,分別代表兩份不同的喜悅感,中間有一個空格,並且喜悅感較小的先輸出。

Sample Input

2
6
2 2 1 1 3 4
4
1 1 3 4

Sample Output

3 4
3 4

HINT
題解:暴力肯定是不行的。因為除了答案,剩下的都是成對出現的,想到異或,求的答案的異或和(>0)。而和二進位制的某一個1一定是其中一個答案貢獻的。於是將這些數分成該位1/0兩部分,分別異或,求的答案。
程式碼:

#include<bits/stdc++.h>
#define ll long long
using namespace
std; const ll N=1e6+10; ll a[N]; int main() { int t,n; scanf("%d",&t); while(t--) { scanf("%d",&n); ll x=0; for(int i=1;i<=n;i++) { scanf("%lld",&a[i]); x^=a[i]; } ll num1,num2; num1=num2=0; ll tmp=1
; while(!(tmp&x)) tmp<<=1; for(int i=1;i<=n;i++) { if(a[i]&tmp) num1^=a[i]; else num2^=a[i]; } printf("%lld %lld\n",min(num1,num2),max(num1,num2)); } }