最大异或对 (Trie)
在给定的N个整数A1,A2……ANA1,A2……AN中选出两个进行xor(异或)运算,得到的结果最大是多少?
输入格式
第一行输入一个整数N。
第二行输入N个整数A1A1~ANAN。
输出格式
输出一个整数表示答案。
数据范围
1≤N≤1051≤N≤105,
0≤Ai<2310≤Ai<231
输入样例:
3
1 2 3
输出样例:
3
将输入的数字的二进制表示构成一个Trie,然后经过 n 次查询即可
查询过程: 异或,相同为0,不同为1,最大值就是尽可能不同,并且不同的位尽可能是高位即可,恰好可以通过Trie进行查询
#include <bits/stdc++.h>
using namespace std;
const int N = 1e5 + 10;
int trie[N * 32][2], tot = 1;
void insert(int Number){
int p = 1;
for (int i = 31; i >= 0; i--){
int t = (Number >> i) & 1;
if(!trie[p][t])trie[p][t] = ++tot;
p = trie[p][t];
}
}
int search(int Number){
int p = 1;
int res = 0;
for (int i = 31; i >= 0; i--){
int t = (Number >> i) & 1;
if(t == 1){
if(trie[p][0]){
p = trie[p][0];
res += (1 << i);
}
else p = trie[p][1];
}
else if(t == 0){
if(trie[p][1]){
p = trie[p][1];
res += (1 << i);
}
else p = trie[p][0];
}
}
return res;
}
int a[N];
int main()
{
int n;
scanf("%d", &n);
for (int i = 1; i <= n; i++){
scanf("%d", &a[i]);
insert(a[i]);
}
int res = 0;
for (int i = 1; i <= n; i++){
res = max(res, search(a[i]));
}
printf("%d\n", res);
return 0;
}
下面的两个代码也是可以的,但是提交后会显示段错误,应该是出错在字符串上面了,因为我直接将数字的二进制表示写了出来,然后就段错误了,,,
#include <bits/stdc++.h>
using namespace std;
char *getBinary(int Number){
char *S = (char*)malloc(sizeof(char) * 40);
int k = 0;
while (Number){
S[k++] = Number % 2 + '0';
Number /= 2;
}
while (k < 32){
S[k++] = '0';
}
S[k] = '\0';
reverse(S, S + k);
return S;
}
int cal(char *S){
int len = strlen(S);
int res = 0, tt = 1;
for (int i = len - 1; i >= 0; i--){
res += (S[i] - '0') * tt;
tt *= 2;
}
return res;
}
const int N = 1e5 + 10;
char s[N];
int trie[N * 32][2], tot = 1, color[N], a[N];
void insert(char *S){
int len = strlen(S);
int p = 1;
for (int i = 0; i < len; i++){
int c = S[i] - '0';
if(trie[p][c] == 0){
trie[p][c] = ++tot;
}
p = trie[p][c];
}
color[p]++;
}
int search(char *S){
int len = strlen(S);
char *t = (char *)malloc(sizeof(char) * 40);
int k = 0, p = 1;
for (int i = 0; i < len; i++){
if(S[i] == '0'){
if(trie[p][1]){
t[k++] = '1';
p = trie[p][1];
}
else t[k++] = '0', p = trie[p][0];
}
else if(S[i] == '1'){
if(trie[p][0]){
t[k++] = '1';
p = trie[p][0];
}
else t[k++] = '0', p = trie[p][1];
}
}
t[k] = '\0';
return cal(t);
}
int main()
{
int n;
scanf("%d", &n);
for (int i = 1; i <= n; i++){
scanf("%d", &a[i]);
insert(getBinary(a[i]));
}
int res = 0;
for (int i = 1; i <= n; i++){
res = max(res, search(getBinary(a[i])));
}
printf("%d\n", res);
return 0;
}
#include <bits/stdc++.h>
using namespace std;
string getBinary(int Number){
// char *S = (char*)malloc(sizeof(char) * 32);
string S = "";
while (Number){
S.push_back(Number % 2 + '0');
// S[k++] = Number % 2 + '0';
Number /= 2;
}
int len = S.length();
while (len < 32){
S.push_back('0');
len++;
}
reverse(S.begin(), S.end());
return S;
}
int cal(string S){
int len = S.length();
int res = 0, tt = 1;
for (int i = len - 1; i >= 0; i--){
res += (S[i] - '0') * tt;
tt *= 2;
}
return res;
}
const int N = 1e5 + 10;
char s[N];
int trie[N * 32][2], tot = 1, color[N], a[N];
void insert(string S){
int len = S.length();
int p = 1;
for (int i = 0; i < len; i++){
int c = S[i] - '0';
if(trie[p][c] == 0){
trie[p][c] = ++tot;
}
p = trie[p][c];
}
color[p]++;
}
int search(string S){
int len = S.length();
string t = "";
int k = 0, p = 1;
for (int i = 0; i < len; i++){
if(S[i] == '0'){
if(trie[p][1]){
t.push_back('1');
p = trie[p][1];
}
else t.push_back('0'), p = trie[p][0];
}
else if(S[i] == '1'){
if(trie[p][0]){
t.push_back('1');
p = trie[p][0];
}
else t.push_back('0'), p = trie[p][1];
}
}
return cal(t);
}
int main()
{
int n;
scanf("%d", &n);
for (int i = 1; i <= n; i++){
scanf("%d", &a[i]);
insert(getBinary(a[i]));
}
int res = 0;
for (int i = 1; i <= n; i++){
res = max(res, search(getBinary(a[i])));
}
printf("%d\n", res);
return 0;
}
本文来自博客园,作者:correct,转载请注明原文链接:https://www.cnblogs.com/correct/p/12862021.html

浙公网安备 33010602011771号