• codeforces 1285D. Dr. Evil Underscores(字典树)


    链接:https://codeforces.com/problemset/problem/1285/D

    题意:给n个数a1,a2,a3.....an,找到一个数X,使得X 异或所有的ai ,得到的max(X xor ai)最小,输出这个值。

    思路:a的范围是0~230,我们可以以01二进制的形式建一棵深度为30的字典树,每个数a的二进制序列插入到字典树中去,例如5 = 101,那么101按位插入到字典树中去。然后从根开始遍历,在字典树上dp,因为该字典树建完后是一棵二叉树,所以分支情况就两种,下一位是0或1,那么如果只遇到1就往1这个分支走,这一位便没有贡献,如果只遇到0就往0这个分支走,这一位也没有贡献,如果遇到的是0和1两个分支,那么必定要加上这一位的贡献,然后递归01两个分支,两者再去min,一直递归到最后一位。

    AC代码:

     1 #include<iostream>
     2 #include<vector>
     3 #include<cstdlib>
     4 #include<cstdio>
     5 #include<algorithm>
     6 #include<cmath>
     7 #include<cstring>
     8 #include<queue>
     9 #include<map>
    10 using namespace std;
    11 typedef long long ll;
    12 int trie[6000005][2],cnt ;
    13 //bool exist[31*31];// 该结点结尾的字符串是否存在
    14 void insert(int a){//建trie树 
    15     int p = 0;
    16     for(int i = 29;i>=0;i--){
    17         int c = (a>>i)&1;
    18         if(!trie[p][c]) trie[p][c] = ++cnt; // 如果没有,就添加结点
    19         p = trie[p][c];
    20     }
    21 //    exist[p] = 1;
    22 } 
    23 ll solve(ll cur,int k){
    24     if(k == -1) return 0;
    25     if(trie[cur][0] == 0){
    26         return solve(trie[cur][1],k-1);
    27     }
    28     else if(trie[cur][1] == 0){
    29         return solve(trie[cur][0],k-1);
    30     }
    31     else{
    32         return (1<<k)+min(solve(trie[cur][0],k-1),solve(trie[cur][1],k-1));
    33     }
    34 }
    35 int main()
    36 {
    37     int n;
    38     cin>>n;
    39     for(int i = 0;i<n;i++){
    40         ll a;cin>>a;
    41         insert(a);
    42     }
    43     ll ans = solve(0,29);
    44     cout<<ans;
    45     return 0;
    46 }
  • 相关阅读:
    Intellij Idea快捷键
    JSP学习
    java 多线程
    java IO流(二)
    java IO流(一)
    java异常处理
    java集合类
    Java常见面试题
    面向对象编程的理解
    软件测试之BUG分析定位概述(QA如何分析定位BUG)(转载)
  • 原文地址:https://www.cnblogs.com/AaronChang/p/12192286.html
Copyright © 2020-2023  润新知