题目:
https://vjudge.net/problem/CSU-1216
题意:
给定一些数,求这些数中两个数的异或值最大的那个值
Input
多组数据。第一行为数字个数n,1 <= n <= 10 ^ 5。接下来n行每行一个32位有符号非负整数。
Output
任意两数最大异或值
思路:
最暴力的方法是枚举两个数,这样显然不可行,当枚举
x
时,怎么找到另一个数字
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
const int N = 100000 + 10, M = 2;
struct node
{
node *next[M];
void init()
{
memset(next, 0, sizeof next);
}
}trie[N*25], *root;
int tot;
int len = 31;
int a[N];
node* new_node()
{
trie[tot].init();
return trie + tot++;
}
void trie_init()
{
tot = 0;
root = new_node();
}
void trie_insert(int val)
{
node *p = root;
for(int i = len-1; i >= 0; i--)
{
int j = 1 & (val>>i);
if(p->next[j] == NULL) p->next[j] = new_node();
p = p->next[j];
}
}
int trie_query(int val)
{
node *p = root;
int ans = 0;
for(int i = len-1; i >= 0; i--)
{
int j = ! (1 & (val>>i));//j是val在当前位置上的相反数,即val在当前位是0,则j=1,否则反之
if(p->next[j] != NULL)//相反数存在,则异或后当前位的二进制为1
{
p = p->next[j];
ans = ans * 2 + 1;
}
else //否则为0
{
p = p->next[!j];
ans = ans * 2 + 0;
}
}
return ans;
}
int main()
{
int n;
while(~ scanf("%d", &n))
{
trie_init();
int ans = 0;
for(int i = 1; i <= n; i++)
{
scanf("%d", &a[i]);
trie_insert(a[i]);
ans = max(ans, trie_query(a[i]));
}
printf("%d\n", ans);
}
return 0;
}