欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

【字典树】异或最大值

程序员文章站 2022-07-14 14:39:52
...

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;
    }
}