只想到这种丑陋的办法
#include <stdio.h>
int main( void )
{
unsigned t;
scanf( "%u", &t );
while( t-- )
{
unsigned n;
scanf( "%u", &n );
unsigned zero_cnt = 0;
unsigned a[32][2] = { 0 };
for( unsigned i=0; i!=n; ++i )
{
unsigned value;
scanf( "%u", &value );
zero_cnt += (value==0);
for( unsigned i=0; i!=32; ++i )
a[i][value>>i&1] ^= value;
}
for( unsigned i=0; i!=32; ++i )
{
if( (zero_cnt%2!=0) == (a[i][0]==0 || a[i][1]==0) )
{
printf( "%u %u\n", a[i][1]<a[i][0]?a[i][1]:a[i][0], a[i][0]<a[i][1]?a[i][1]:a[i][0] );
break;
}
}
}
}
设不相同的两个数为 x 和 y
因为 x 和 y 不同,所以这两个数必然有至少一个bit不相同
根据这个bit是0还是1,分成两组,那么x和y就必然分在两个不同的组内
每个组分别进行各自元素的异或,就得到了x和y
但是,现在不知道哪个bit不相同,只能将32个bits分别处理(这就是代码中定义 unsigned a[32][2] 的原因)
组内各自异或后得到两个可能数值对,分别是 {x,y} 和 {0,x^y}
这两个数值对中,我也不知道哪个数值对是{x,y}
所以我又统计 0 的数目,(这就是代码中定义 unsigned zero_cnt 的原因)
如果0的数目是偶数,那么x和y都不是0,那我只要在这两个数值对中选都不是0的那个就行了
如果0的数目是奇数,那么x和y必然有一个是0;如果x和y必然有一个是0,那么 {x,y} 和 {0,x^y} 是相同的,所以我只要在这两个数值对中选其中一个是0的那个就行了。