题意:
给出n个整数:A1,A2,A3,A4,…An,从中任意选出两个数进行异或求最大值。
思路:
把给出的数Ai化为二进制,从最大位开始插入字典树,假设都从第32位插入(保证数据的一致性)。插入完毕后,便利每一个数,根据异或的特点,每次优先走与这个数插入树中的边不一样的边,即:若当前位是0,则走1,若当前位是1,则反之。因为是从最高位查起,若没有与当前位相同的边,就走与当前位相同的边。
注意:插入的时候要从高位进行插入
十进制转二进制求每一位:设一十进制数x,则int id=(x>>t)&1,id代表x化为二进制的第t+1位的值。向右移动t位,再取对改变后的数的最后一位,即为:第t+1位的值。
代码:
#include<math.h>
#include<stdio.h>
#include<string.h>
#include<algorithm>
using namespace std;
const int N=1e5+1;
int ch[32*N][2];
int n,tot;
int a[N];
void insert(int x)
{
int u=1;
for(int i=31; i>=0; i--){
int c=(x>>i)&1; //右移i位,得到x二进制第i+1位的值
if(!ch[u][c])
ch[u][c]=++tot;
u=ch[u][c];
}
}
int find(int x)
{
int u=1,ans=0;
for(int i=31; i>=0; i--){
int c=(x>>i)&1;
if(ch[u][1-c]){
u=ch[u][1-c];
ans+=pow(2,i); //记录数值
}
else u=ch[u][c];
}
return ans;
}
int main()
{
tot=1;
scanf("%d",&n);
for(int i=1; i<=n; i++){
scanf("%d",&a[i]);
insert(a[i]);
}
int maxx=-1; //记录最大值
for(int i=1; i<=n; i++)
maxx=max(maxx,find(a[i]));
printf("%d\n",maxx);
return 0;
}