异或最大值【字典树】

1216: 异或最大值

题目链接(点击)

Submit Page    Summary    Time Limit: 2 Sec     Memory Limit: 128 Mb     Submitted: 1374     Solved: 503    

Description

给定一些数,求这些数中两个数的异或值最大的那个值

Input

多组数据。第一行为数字个数n,1 <= n <= 10 ^ 5。接下来n行每行一个32位有符号非负整数。

Output

任意两数最大异或值

Sample Input

3
3
7
9

Sample Output

14

思路:

像是一个模板题但是里面用到了:

1.题目是要求在已知的数组选出异或后结果最大的 可以想象两个数其中一定有一个是数组中的最大值

2.异或符号在电脑中的使用

  具体讲解可以看下另一篇博客:

https://blog.csdn.net/weixin_43350051/article/details/88085514

AC代码:

数组忘记初始化了 但也A了

#include<bits/stdc++.h>
using namespace std;
const int MAX=1e5;
int maxx=-MAX;
int top;
int tir[MAX+5][5],num[MAX+5];
int a[MAX+5],b[MAX+5];
void add(int *a)
{
    int root=0;
    for(int i=31;i>=0;i--){
        int id=a[i];
        if(tir[root][id]==0){
            tir[root][id]=++top;
        }
        root=tir[root][id];
    }
}
int find(int *b)
{
    int root=0,count=0;
    for(int i=31;i>=0;i--){
        int id=b[i];
        if(tir[root][id]==0){
            if(id==0){
                id=1;
            }
            else{
                id=0;
            }
        }
        if(tir[root][id]==0){
            break;
        }
        num[count++]=id;
        root=tir[root][id];
    }
    int sum=0,count1=1;
    for(int i=count-1;i>=0;i--){
        sum+=num[i]*count1;
        count1*=2;
    }
    return sum^maxx;
}
int main()
{
    int m,n;
    while(~scanf("%d",&n)){
        for(int i=0;i<n;i++){
            scanf("%d",&m);
            maxx=max(maxx,m);
            for(int i=31;i>=0;i--){
                a[i]=m&(1<<i)?1:0;
            }
            add(a);
        }
        for(int i=31;i>=0;i--){
            b[i]=maxx&(1<<i)?0:1;
        }
        int sum=find(b);
        printf("%d\n",sum);
        return 0;
    }
}

 

posted @ 2019-03-03 19:47  XJHui  阅读(404)  评论(0编辑  收藏  举报