Description
給定一些數,求這些數中兩個數的異或值最大的那個值
Input
第一行爲數字個數n,1 <= n <= 10 ^ 5。接下來n行每行一個32位有符號非負整數。
Output
任意兩數最大異或值
Sample Input
3
3
7
9
Sample Output
14
/*
類型:字典樹+貪心
分析:建一棵01字典樹,樹的深度就是整數的值的位數,然後根據異或的性質進行貪心
吐槽:剛開始從低位向高位建樹,WA了幾次沒想出所以然,後面才發現,低位開始建樹的貪心策略是錯的
因爲在查找的過程中從高位的路線轉移到低位的路線,最後前期貪心的結果沒高位的那麼多,心塞
*/
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<iostream>
using namespace std;
const int len = 31;
typedef struct Trie{
Trie *next[2];
}Trie;
Trie root;
void createTrie(int x)
{
Trie *p = &root, *q;
for(int i=len;i>=0;i--){
bool id = x&(1<<i);
if(p->next[id] == NULL){
q = (Trie *)malloc(sizeof(root));
for(int j=0;j<2;j++)
q->next[j] = NULL;
p->next[id] = q;
p = p->next[id];
}
else{
p = p->next[id];
}
}
}
int findTrie(int x)
{
int val=0;
Trie *p = &root;
for(int i=len;i>=0;i--){
bool id = x&(1<<i);
if(p->next[!id]!=NULL){
val=val|(1<<i);
p = p->next[!id];
}
else p = p->next[id];
}
return val;
}
void deal(Trie* T)
{
for(int i=0;i<2;i++)
{
if(T->next[i]!=NULL)
deal(T->next[i]);
}
free(T);
}
int main()
{
//freopen("F:\\input.txt", "r", stdin);
int n;
while(~scanf("%d",&n)){
int x,ans=0;
for(int i=0;i<2;i++)root.next[i] = NULL;
while(n--){
scanf("%d",&x);
createTrie(x);
ans=max(ans,findTrie(x));
}
printf("%d\n",ans);
for(int i=0;i<2;i++){
if(root.next[i]!=NULL)
deal(root.next[i]);
}
}
return 0;
}