传送门:http://acm.hdu.edu.cn/showproblem.php?pid=4825
【分析】这题需要了解位运算,首先建立字典树存入这个数的二进制,查找的时候当遇到,值不相同时,意味着,异或结果一定为1 那么我们就要进入 值不同的分支,最后才能找到最大 ,要从高位找起,这样才可以保证异或值最大。
#include<iostream>
#include<cstring>
#include<algorithm>
using namespace std;
void insert(int x);
int find(int x);
struct Node
{
int t;
Node *next[2];
Node()
{
t=0;
memset(next,NULL,sizeof(next));
}
};
Node *root;
int main()
{
int t;
scanf("%d",&t);
for(int i=1;i<=t;i++)
{
root=new Node;
int n,m;
scanf("%d%d",&n,&m);
for(int j=0;j<n;j++)
{
int x;
scanf("%d",&x);
insert(x);
}
printf("Case #%d:\n",i);
while(m--)
{
int x;
scanf("%d",&x);
printf("%d\n",find(x));
}
}
}
void insert(int x)
{
int a[33];
int y=x;
Node *p,*q;
p=root;
for(int i=1;i<=32;i++) //从高向低位找 优先选择异或的
{
a[i]=(x>>(32-i))&1; //当i=1,就是把这个数的二进制往右移动31位,例如:7为111,1为001
//让7的最左边那位与1的最右边这位1按位与&,则就推出来了7的左31位是什么
}
for(int i=1;i<=32;i++)
{
if(p->next[a[i]]==NULL)
{
q=new Node;
p->next[a[i]]=q;
}
p=p->next[a[i]];
}
p->t=y;
}
int find(int x)
{
int a[33];
Node *p;
p=root;
for(int i=1;i<=32;i++)
{
a[i]=(x>>(32-i))&1;
}
for(int i=1;i<=32;i++)
{
if(p->next[!a[i]]!=NULL) //这位数的反存在 则就取反
p=p->next[!a[i]];
else
p=p->next[a[i]];
}
return p->t;
}