For each test case, the first line contains an integer n(n <= 100000), the next line contains a1, a2, a3, ......, an(0 <= ai <= 1000000000);
2 4 1 2 3 4 3 7 12 5
7 11
题意:给出n个数字,找出其中两个数字异或(^)的最大值。
分析:可以把数字拆成二进制,构建字典树,添加进数字后,遍历n个数寻找异或的最大值。
0 ^ 1 = 1
1 ^ 0 = 1
0 ^ 0 = 0
1 ^ 1 = 0
所以可以在查找的时候先把二进制数求非(!),然后在字典树中查找是否有这一位,再用或(|)转为十进制得到答案。
代码如下:
#include <set> #include <map> #include <queue> #include <cmath> #include <vector> #include <cctype> #include <cstdio> #include <cstring> #include <iostream> #include <algorithm> #define MX 100005 #define mod 835672545 #define INF 0x3f3f3f3f #define LL long long using namespace std; int n, tot; LL a[MX]; struct node{ int nxt[2]; }tree[MX*13]; void add(LL x){ int now = 0; for(int i = 31; i >= 0; i--){ int t = (x >> i)&1; if(tree[now].nxt[t] == 0){ tree[now].nxt[t] = ++tot; } now = tree[now].nxt[t]; } } LL query(LL x){ int now = 0; LL ans = 0; for(int i = 31; i >= 0; i--){ int t = !((x >> i)&1); if(tree[now].nxt[t] != 0){ ans |= (1 << i); now = tree[now].nxt[t]; } else now = tree[now].nxt[!t]; } return ans; } int main(){ int t; scanf("%d", &t); while(t--){ tot = 0; memset(tree, 0, sizeof(tree)); scanf("%d", &n); for(int i = 0; i < n; i++){ scanf("%I64d", &a[i]); add(a[i]); } LL ans = 0; for(int i = 0; i < n; i++){ ans = max(ans, query(a[i])); } printf("%I64d\n", ans); } return 0; }