主要思路
如何找到一对异或值最大的数字呢?我们先从二进制计算(位运算)本身讲起,如果我们要保证Xor值更大,那么我们就需要尽可能多的1,除此之外,1的位置也非常重要,在一些情况下靠前更好。我们可以考虑从最高位为起点向最低位建立一个 Trie 树。我们记num[i]表示第i位的0或1状态。建立 Trie 树之后,我们计算出每个数所对应的异或值最大的值。我们的策略是:
- 我们已经从第 30 位移动到第 i 位了,我们期望的对应的数位是1\; xor \; 1,如果在节点上有这个值,那么正常向下递归。
- 如果没有我们期望的数字,那么我们只能选同位数了,向下递归时要注意端点和上一条不一样。
具体的请看代码:
代码
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// CH1602.cpp | |
#include <iostream> | |
#include <cstdio> | |
using namespace std; | |
const int maxn = 100000 * 40; | |
int trie[maxn][2], arr[maxn], n, current = 2; | |
void insert(int num) | |
{ | |
int pnode = 1; | |
for (int i = 30; i >= 0; i--) | |
{ | |
int bit = (num >> i) & 1; | |
if (trie[pnode][bit] == 0) | |
trie[pnode][bit] = current++; | |
pnode = trie[pnode][bit]; | |
} | |
} | |
int getBiggest(int num) | |
{ | |
int ans = 0, pnode = 1; | |
for (int i = 30; i >= 0; i--) | |
{ | |
int bit = (num >> i) & 1; | |
if (trie[pnode][bit ^ 1] != 0) | |
pnode = trie[pnode][bit ^ 1], ans |= (1 << i); | |
else | |
pnode = trie[pnode][bit]; | |
} | |
return ans; | |
} | |
int main() | |
{ | |
scanf("%d", &n); | |
for (int i = 0; i < n; i++) | |
scanf("%d", &arr[i]), insert(arr[i]); | |
int ans = 0; | |
for (int i = 0; i < n; i++) | |
ans = max(ans, getBiggest(arr[i])); | |
printf("%d", ans); | |
return 0; | |
} |