原题链接:http://acm.csu.edu.cn/OnlineJudge/problem.php?id=1240
这道题已经做了很久了,加入给足够大的内存,谁都会做。
在一个数列中找一个只出现一次的数,第一反应应该是对数列进行“异或”运算,这道题也是如此。两个相同的数异或结果为0。对于这道题,给出互质的概念,这其中隐藏的信息就是在给出的数列中多次出现的数只会出现偶数次,因为欧拉函数的值只会是偶数(n>1)。这道题就不攻自破。
设数列为A,两个只出现一次的数分别位a,b。首先求出A的总异或值s,找出s的第一个不为0的二进制位k,那么在a,b中只会有一个数的k位为1,第二次就用s对所有k位为1的数进行异或,得到的结果就是a或者是b。那么另外的数根据a^b=s进行一次异或运算就能算出另外一个数了。
#include <stdio.h> #include <string.h> #include <algorithm> int main() { int n, k; while(scanf("%d%d", &n, &k) != EOF) { int s = 0, a; for(int i = 0; i < k; i++) { scanf("%d", &a); s ^= a; } int t1 = s; int t2 = s; int p = 0; while((t1&1) == 0) { t1 >>= 1; p++; } for(int i = 0; i < k; i++) { scanf("%d", &a); if(((a>>p)&1) == 1) t2 ^= a; } int a1 = t2; int a2 = s ^ a1; printf("%d %d ", std::min(a1, a2), std::max(a1, a2)); } return 0; }