2014年02月28日

题目链接:http://acm.nbut.cn/Problem/view.xhtml?id=1314
求的是一对对基友成功牵手后留下的两个孤独的男人的编号= =。
常规的哈希在这里超时,这时候我们用了'^',按位异或,用来快速求得这两个不同数的异或值。

t ^= a[i];

因为我们知道,剩下的两个数是绝对不同的,所以按位异或后的数二进制表示时至少有一位上为1,我们从低位(从右到左)开始找到这个1,
                for(i = 1;i <= 32;i++)
{
s = t % 2;
if(s == 1)
{
s = i;
break;
}
t >>= 1;
}


然后根据这个1的位置,我们把输入的n个数字里分为两组,一组在这个1的位置上是1;

if((a[i] >> (s-1)) % 2 == 0)

再分别对两组数按位异或,每组得到的那个是便是所求的了。
代码如下:

#include<stdio.h>
#include<string.h>
#include<algorithm>
using namespace std;
#define m 1000005
int a[m], b[m], c[m];
int main()
{
int i, n, s;
while(~scanf("%d",&n))
{
scanf("%d",&a[0]);
int t = a[0];
for(i = 1;i < n;i++)
{
scanf("%d",&a[i]);
t ^= a[i];
}
for(i = 1;i <= 32;i++)
{
s = t % 2;
if(s == 1)
{
s = i;
break;
}
t >>= 1;
}
int z = 0, x = 0;
for(i = 0;i < n;i++)
{
if((a[i] >> (s-1)) % 2 == 0)
{
b[z] = a[i];
z++;
}
else
{
c[x] = a[i];
x++;
}
}
int q = b[0], w = c[0];
for(i = 1;i < z;i++)
{
q ^= b[i];
}
for(i = 1;i < x;i++)
{
w ^= c[i];
}
printf("%d %d\n",min(q,w),max(q,w));
}
return 0;
}

你可能感兴趣的:(2014年02月28日)