4
这道题最常规的解法就是简单的循环,一个个的比较判断那个数的异或最大,时间复杂度为0(TNM),在OJ平台上肯定是时间会超时的。
因此,应该采用其他的方法,减少计算的次数,降低时间复杂度。首先要知道的是什么情况下,给定一个数a,如何在一组数据中找到其异或的最大值。一般我们现将数首先取反。在该组数据中与已知的异或最大的数的特点就是从该数二进制的最高开始匹配,尽可能与~a的二进制相同。
基于此,第一种解法就是使用二叉树,左边表示0,右边表示1。所以该树的深度最多为32。在匹配的时候从树开始,往下匹配,到叶子节点时,就是其最大的异或数。该算法的缺点就是要构建二叉树,浪费了一点时间(可以自己去算一算)。但是匹配的时候大大减少了时间。
第二种解法就是现将一组数进行排序,然后采用二分查找的方式去查找数据,缺点就是要排序。2种算法都是常见的减少时间复杂度的经典算法。
代码如下:
/*#include<iostream> #include<stdio.h> #include<stdlib.h> #include<fstream> using namespace std; #define MAXSIZE 100000 typedef bool bits; typedef struct bitTree { bits data; bitTree *left,*right; //bitTree(bits _data=0):data(_data),left(NULL),right(NULL){} }bitTree; unsigned int a[MAXSIZE]; unsigned int b[MAXSIZE]; int length,question; void create(bitTree *root,unsigned int temp) { int i=1,j=32; bitTree *q=root; bitTree *child; bits middle_bits; while(i<=j) { middle_bits=temp>>31; if(middle_bits==0) { if(q->left==NULL) { child=(struct bitTree *)malloc(sizeof(struct bitTree)) ; child->data=0; child->left=child->right=NULL; q->left=child; } q=q->left; } else { if(q->right==NULL) { child=(struct bitTree *)malloc(sizeof(struct bitTree)) ; child->data=1; child->left=child->right=NULL; q->right=child; } q=q->right; } temp=temp<<1; i++; } } ofstream ofs("d.txt"); void fun(bitTree *root) { bitTree* ttemp=root; unsigned int result; bits middle_bits; int i,j=1,k=32; for(i=0;i<question;i++) { result=0; ttemp=root; j=1; unsigned int temp=~b[i]; while(j<=k) { middle_bits=temp>>31; if(middle_bits==0) { if(ttemp->left!=NULL) { result=result<<1; ttemp=ttemp->left; } else { result=(result<<1)+1; ttemp=ttemp->right; } } else { if(ttemp->right!=NULL) { result=(result<<1)+1; ttemp=ttemp->right; } else { result=result<<1; ttemp=ttemp->left; } } j++; temp=temp<<1; } // printf("%u\n",result); ofs<<result<<" "; } ofs<<endl; } int main() { //ifstream ifs("a.txt"); //cin.rdbuf(ifs.rdbuf()); freopen("a.txt","r",stdin); int number; scanf("%d",&number); bitTree *root; int i,k=1; while(k<=number) { scanf("%d%d",&length,&question); for(i=0;i<length;i++) scanf("%u",&a[i]); for(i=0;i<question;i++) scanf("%u",&b[i]); root=(struct bitTree *)malloc(sizeof(struct bitTree)) ; root->data=1; root->left=root->right=NULL; for(i=0;i<length;i++) create(root,a[i]); printf("Case #%d:\n",k); fun(root); k++; } }*/
第二种解法:
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cmath>
#include<fstream>
using namespace std;
const int maxn=100000+5;
const int inf=1<<31;
unsigned int s[maxn];
int main(){
freopen("d.txt","r",stdin);
ofstream fs( "e.txt");
int kase;
cin>>kase;
for(int run=1;run<=kase;run++){
printf("Case #%d:\n",run);
int n,m;
cin>>n>>m;
for(int i=0;i<n;i++)
scanf("%d",&s[i]);
sort(s,s+n);
while(m--){
unsigned int x;
scanf("%d",&x);
x=~x;
int L=0,R=n-1;
unsigned int bit=inf;
while(bit){
if(L==R) break;
unsigned int y=bit&x;
if(y){
int l=L,r=R,mid,ans=-1;
while(l<=r){
mid=(l+r)/2;
if(s[mid]&bit){
ans=mid;
r=mid-1;
}
else
l=mid+1;
}
if(ans!=-1)
L=ans;
}
else{
int l=L,r=R,mid,ans=-1;
while(l<=r){
mid=(l+r)/2;
if((s[mid]&bit)==0){
ans=mid;
l=mid+1;
}
else
r=mid-1;
}
if(ans!=-1)
R=ans;
}
bit=bit>>1;
}
// printf("%u\n",s[L]);
fs<<s[L]<<" ";
}
fs<<endl;
}
}
原文:http://blog.csdn.net/bb2b2bbb/article/details/26162901