您的位置:首页 > 其它

CSU 1216 异或最大值【字典树】

2016-10-19 00:57 405 查看
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;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: