[模拟赛]异或最大值 maxinum
此题在考试时用暴力,暴了30分。
献上30分代码:
#include<stdio.h> int a[100005]; int main() { int n,t,c,i,max,j,d; freopen("maximum.in","r",stdin); freopen("maximum.out","w",stdout); scanf("%d",&t); while(t--) { max=0; scanf("%d%d",&n,&c); for(i=1;i<=n;i++) scanf("%d",&a[i]); if(c==1) { for(i=1;i<=n;i++) for(j=i+1;j<=n;j++) { d=a[i]&a[j]; if(d>=max)max=d; } } if(c==2) { for(i=1;i<=n;i++) for(j=i+1;j<=n;j++) { d=a[i]^a[j]; if(d>=max)max=d; } } if(c==3) { for(i=1;i<=n;i++) for(j=i+1;j<=n;j++) { d=a[i]|a[j]; if(d>=max)max=d; } } printf("%d\n",max); } fclose(stdin); fclose(stdout); return 0; }
注意与运算符(&),或运算符(|),异或运算符(^)
详细解说:http://www.cnblogs.com/wisdom-jie/p/7732940.html
正解:
1、0-1字典树:
这里其实是就是二叉树,之所以叫做字典树是因为我们的算法把一个数当成了一个31位的字符串来看,比如1就是三十个零外加一个一,这一部分还是比较简单的。
2、贪心找最大异或值:
异或运算有一个性质,就是对应位不一样为1,我们要让结果最大化,就要让越高的位置为1。我们找跟一个数的异或结果最大的数,就从树的根结点(最高位)开始找,如果对应位置这个数是0,优先去找那一位为1的数,找不到才去找0;如果对应位置这个数是1,优先去找那一位为0的数,找不到才去找0;最终找到的数就是跟这个数异或结果最大的数。n个数,每个数找一个这样的数并算出结果求其中的最大值,可以得到答案。
参考代码如下:
#include <cstdio> #include <cstring> #include <algorithm> using namespace std; int n,a[100005],tmp[35]; struct node { int val; node *left, *right; node(int value=-1) { val = value; left = right = NULL; } }; node *head = NULL; void cal(int num) { memset(tmp,0,sizeof(tmp)); int cnt=0; while(num) { tmp[cnt++]=num%2; num/=2; } for(int i=0;i<15;i++) swap(tmp[i],tmp[30-i]); } void insert(node* &head, int index, int &num) { if(index+1==31) { head->val = num; return; } if(tmp[index+1]==0 && !head->left) head->left = new node(-1); if(tmp[index+1]==1 && !head->right) head->right = new node(-1); if(tmp[index+1]==0) insert(head->left,index+1,num); if(tmp[index+1]==1) insert(head->right,index+1,num); } int dfs(node* &head,int index) { if(index+1==31) return head->val; if(tmp[index+1]==0) { if(head->right) { return dfs(head->right,index+1); } else { return dfs(head->left,index+1); } } else { if(head->left) { return dfs(head->left,index+1); } else { return dfs(head->right,index+1); } } } int main() { while(scanf("%d",&n)) { for(int i=0;i<n;i++) scanf("%d",&a[i]); head = new node(-1); for(int i=0;i<n;i++) { cal(a[i]); insert(head,-1,a[i]); } int ans=0; for(int i=0;i<n;i++) { cal(a[i]); ans = max(ans, a[i]^dfs(head,-1)); } printf("%d\n",ans); } return 0; }