1 秒
内存限制:32 兆
特殊判题:否
提交:1139
解决:314
8 2 4 3 6 3 2 5 5
4 6
假设a,b为数组中只出现了一次的两个数,
由于相同的两个数进行 按位异或 运算得到 0, 而0 和任何数值进行 按位异或 得到该数本身。
对数组中所有数值进行异或运算,而a,b两数只出现了一次,那么最终的结果等于 a按位异或b,得到andr
可知andr上必有一位为1,并且 a,b两数在该位上不同(否者 按位异或后就得0)。
我们根据andr上该1位对数组中的所有数值进行分类,该位为1的为1组,为0的为1组。
这样就转化为了 一个数组只有一个数出现一次,其它数出现两次的问题。
对两组数字分别进行 按位异或 运算,就可以得到要求的两个不同数。
在求andr上为1的位时有个技巧 andr = andr &(-andr)
-andr是通过对andr按位取反加1所得, andr & (-andr)就可以得到最低位的1所在位
源程序
输入输出 用scanf print,否则程序会超时
#include <iostream> #include <stdio.h> int nums[1000000]; int main() { int n=0 ; int andr = 0; while(scanf("%d",&n) != EOF){ int i = 0; andr = 0; while(i<n){ scanf("%d",nums+i); andr^=nums[i]; i++; } andr = andr &(-andr); i = 0; int num1=0; int num2=0; while(i<n){ if(nums[i]&andr) num1^=nums[i]; else num2^=nums[i]; i++; } if(num1<num2) std::cout<<num1<<" "<<num2<<std::endl; else std::cout<<num2<<" "<<num1<<std::endl; } return 0; }