zoukankan      html  css  js  c++  java
  • CSU 1214 找最大异或值

    题目大意:

    给定一堆数,从中找2个数异或得到的最大值

    直接暴力会超时,我们要考虑对于每一个数去匹配找到异或的最大值,我们希望2进制越前面的数尽可能都为1

    所以我们用 0-1 字典树保存这些数,因为一个int型的正整数最多2进制到第30位,所以我们用31层高的字典树保存,第一层为root节点

    每次查询操作都是对于当前数的2进制位查找,如果与之相反的方向有点,就往与之相反的方向向下找,这样异或才为1,没有,就顺着当前相同方向向下找,那样异或值为0

     1 #include <cstdio>
     2 #include <cstring>
     3 #include <iostream>
     4 using namespace std;
     5 
     6 int ans;
     7 struct Node{
     8     int num;
     9     Node *next[2];
    10     Node(){
    11         num = 0;
    12         next[0] = NULL;
    13         next[1] = NULL;
    14     }
    15 };
    16 
    17 Node *root = new Node();
    18 
    19 void add_node(int x)
    20 {
    21     int k = (x&(1<<30)) == 0?0:1;
    22     Node *q;
    23     if(!root->next[k]){
    24         root->next[k] = new Node();
    25     }
    26     q = root->next[k];
    27     for(int i = 29 ; i >= 0 ; i--){
    28         k = (x&(1<<i)) == 0?0:1;
    29         if(!q->next[k])
    30             q->next[k] = new Node();
    31         q = q->next[k];
    32     }
    33     q->num = x;
    34 }
    35 
    36 void query(int x)
    37 {
    38     int k = (x&(1<<30)) == 0?0:1;
    39     Node *q;
    40     if(!root->next[k^1]){
    41         q = root->next[k];
    42     }
    43     else q = root->next[k^1];
    44     for(int i = 29 ; i >= 0 ; i--){
    45         k = (x&(1<<i)) == 0?0:1;
    46         if(!q->next[k^1])
    47             q = q->next[k];
    48         else
    49             q = q->next[k^1];
    50     }
    51   //  cout<<" get num : "<<q->num<<endl;
    52     ans = max(ans , q->num ^ x);
    53 
    54 }
    55 
    56 int main()
    57 {
    58     //freopen("test.in","rb",stdin);
    59     int n,a;
    60     while(~scanf("%d",&n)){
    61         root = new Node();
    62         ans = 0;
    63         for(int i=0;i<n;i++){
    64             scanf("%d",&a);
    65             add_node(a);
    66             query(a);
    67             //cout<<"   jsd: "<<i<<"  "<<ans;
    68         }
    69 
    70         printf("%d
    ",ans);
    71     }
    72     return 0;
    73 }
  • 相关阅读:
    LVM逻辑卷管理练习
    浅谈TCP三次握手和四次分手
    centos模拟创建CA和申请证书
    破解root口令
    shell脚本编程进阶总结
    基于FIFO的串口发送机设计
    流水线方式LUT查表法乘法器
    verilog中有符号整数说明及除法实现
    LUT查表法乘法器所犯下错误。。。。
    似然函数
  • 原文地址:https://www.cnblogs.com/CSU3901130321/p/4044718.html
Copyright © 2011-2022 走看看