最大异或对 (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;
}

 

posted @ 2019-10-09 21:00  correct  阅读(177)  评论(0)    收藏  举报