题目详情 给你 n 个正整数,要求从中至少选一个数,使他们的异或值最小。如果只选一个数,那么他的异或值就是本身。 输入描述: 有多个测试数据,每个测试数据包含两行,第一行是一个正整数n(0 < n < =30),第二行包含 n 个正整数,每个 正整数都小于2^31,以文件结束。 输出描述: 对于每个测试数据,输出答案。 答题说明 输入样例: 1 12345678 2 1 2 3 2 2 3 输出样例: 12345678 1 0 思路: 将n个数分成左右两半,然后对这两半分别单独进行暴力求解所有可能得到的异或值,假设结果分别 保存在res1和res2里面,然后对res1里面的每一个数,求res2里面与该数异或值最小的数,为了快速求得该 最小数,可将res2里面的数放在字典树里面,这就是大体思路了,具体细节可能没讲到,不好意思,表达能 力有限,呵呵。 代码如下: #include <iostream> #include <climits> #include <cmath> #include <algorithm> #include <iomanip> #include <vector> #define inf 0x7fffffff #define MOD 1000000007 using namespace std; struct node{ struct node *lchild, *rchild; }; const int MAXN = 40000; int array[30]; int res1[MAXN], res2[MAXN]; int n, n1, n2; void produce(int* data, int n, int* res, int& num) { int i, j; num = 0; for(i=pow(2, n*1.0)-1; i>=1; i--) { j = i; int pos = 0, k = 0; while(j != 0) { if((j&1) == 1) { k ^= data[pos]; } pos++; j >>= 1; } res[num++] = k; } } void toInsert(node* root, int num) { int i, j; node* p = root; node* q; for(i=29; i>=0; i--) { j = (num & (1<<i)); if(j == 0) { if(p->lchild != NULL) { p = p->lchild; } else { q = new node; q->lchild = q->rchild = NULL; p->lchild = q; p = q; } } else { if(p->rchild != NULL) { p = p->rchild; } else { q = new node; q->lchild = q->rchild = NULL; p->rchild = q; p = q; } } } } int cul(node* root, int num) { int i, j; int res = 0; node* p = root; for(i=29; i>=0; i--) { j = (num & (1<<i)); if(j == 0) { if(p->lchild != NULL) { res *= 2; p = p->lchild; } else { if(p->rchild != NULL) { res = res*2 + 1; p = p->rchild; } else { return inf; } } } else { if(p->rchild != NULL) { res *= 2; p = p->rchild; } else { if(p->lchild != NULL) { res = res*2 + 1; p = p->lchild; } else { return inf; } } } } return res; } int main() { while(scanf("%d", &n)!=EOF) { int i, j; for(i=0; i<n; i++) { scanf("%d", &array[i]); } produce(array, n/2, res1, n1); produce(array+n/2, n - n/2, res2, n2); int result = inf; for(i=0; i<n1; i++) { if(res1[i] < result) result = res1[i]; } for(i=0; i<n2; i++) { if(res2[i] < result) result = res2[i]; } node* root = new node(); root->lchild = root->rchild = NULL; for(i=0; i<n2; i++) { toInsert(root, res2[i]); } for(i=0; i<n1; i++) { j = cul(root, res1[i]); if(j < result) result = j; } printf("%d\n", result); } return 0; }