1080: The Lost Two Cards
Time Limit: 2500 MS Memory Limit: 64 MBSubmit: 27 Solved: 0
[ Submit][ Status][ Web Board]
Description
Having signed a new contract, ArXoR was facing a new task. Given n cards each of which is labeled with an integer bounded in [-2^31,2^31 - 1], the task is to make a duplicate copy of these n cards. As usual, this dull job was assigned to TheBeet. After he finished duplicating, he brought the 2n cards to ArXoR. But after checking these cards again, they found that two cards was lost. It is easy to make another duplication of a card, but not easy to find out which card should be duplicated again. Could you help these two poor guys , especially, TheBeet.
Input
The input contains a single case. The case begin with a integer n bounded in [3, 1000000].
Then 2 * n - 2 lines follows, as mentioned above, each of which indicates the integer on the card in TheBeet and ArXoR's hands.
Output
You should output a single line containing two numbers, the lost cards you have found, with the smaller one at first. Output "poor"(without quote) if the two cards are equal, that means these two poor guys would never find them again.
Sample Input
4
35
4
2
4
35
7
Sample Output
2 7
题意:
从若干个数中找到两个只出现一次的数,其他数字均会出现两次,若所有数字都出现了两次,输出"poor"思路:
一开始联想到的是另一道题,从若干数中找到一个只出现一次的数,其他数字均会出现两次,全异或即可;再看看题目数据范围想到了快速排序,把所有数字排序一次,相等数字必然相邻,时间复杂度O(nlogn)但本题采用异或有最优解,时间复杂度O(n),思路是先对所有数字做一次异或,结果为零时输出"poor",不为零时check为a^b,用dis变量寻找check中的1位,即a,b数字相异的位,再次遍历,根据相异位置把所有数分成两堆,各自异或即可
代码:
#include <stdio.h>
constint maxsize = 1000000;
intmain(){
intarr[maxsize];
intn;
scanf("%d", &n);
n = 2 * n - 2;
intcheck = 0;
for(inti = 0; i < n; ++i){
scanf("%d", &arr[i]);
check = check^arr[i];
}
if(!check){
printf("poor\n");
}
else{
inta = 0, b = 0, dis = 1;
while(!(check & dis)) dis = dis << 1;
for(inti = 0; i < n; ++i){
if(arr[i] & dis)
a = a^arr[i];
elseb = b^arr[i];
}
if(a<b) printf("%d %d\n", a, b);
elseprintf("%d %d\n", b, a);
}
return0;
}