zoukankan      html  css  js  c++  java
  • HDU

    Zeus 和 Prometheus 做了一个游戏,Prometheus 给 Zeus 一个集合,集合中包含了N个正整数,随后 Prometheus 将向 Zeus 发起M次询问,每次询问中包含一个正整数 S ,之后 Zeus 需要在集合当中找出一个正整数 K ,使得 K 与 S 的异或结果最大。Prometheus 为了让 Zeus 看到人类的伟大,随即同意 Zeus 可以向人类求助。你能证明人类的智慧么? 

    Input

    输入包含若干组测试数据,每组测试数据包含若干行。 
    输入的第一行是一个整数T(T < 10),表示共有T组数据。 
    每组数据的第一行输入两个正整数N,M(<1=N,M<=100000),接下来一行,包含N个正整数,代表 Zeus 的获得的集合,之后M行,每行一个正整数S,代表 Prometheus 询问的正整数。所有正整数均不超过2^32。Output对于每组数据,首先需要输出单独一行”Case #?:”,其中问号处应填入当前的数据组数,组数从1开始计算。 
    对于每个询问,输出一个正整数K,使得K与S异或值最大。

    Sample Input

    2
    3 2
    3 4 5
    1
    5
    4 1
    4 6 5 6
    3

    Sample Output

    Case #1:
    4
    3
    Case #2:
    4 

    题目链接

    分析
    首先得清楚,什么时候才求得最大的异或和?就是从高位开始,尽量让每个位不同,这样异或的结果一定最大。所以问题就是如何把所有数的二进制
    表示保存起来,并需要便于访问查找。数最大是2^32,我们可以使用一个树来存,也就是字典树啦,以高位为根。在查找时,尽量选取不同数值的路径。

    #include<iostream>
    #include<cstdio>
    #include<cmath>
    #include<cstdlib>
    #include<algorithm>
    #include<cstring>
    #include <queue>
    #include <vector>
    #include<bitset>
    #include<map>
    #include<deque>
    using namespace std;
    typedef long long LL;
    const int maxn = 1e5+5;
    const int mod = 77200211+233;
    typedef pair<int,int> pii;
    #define X first
    #define Y second
    #define pb push_back
    //#define mp make_pair
    #define ms(a,b) memset(a,b,sizeof(a))
    const int inf = 0x3f3f3f3f;
    #define lson l,m,2*rt
    #define rson m+1,r,2*rt+1
    
    
    struct node{
        int num;
        node *son[2];
        node(){
            num=0;
            son[0]=son[1]=NULL;
        }
    };
    
    node *root;
    
    void Insert(int x){
        int a[32];
        int xx=x;
        node *p=root,*q;
        for(int i=0;i<32;i++){
            a[i]=xx&1;
            xx>>=1;
        }
        for(int i=31;i>=0;i--){
            if(p->son[a[i]]!=NULL){
                p=p->son[a[i]];
            }else{
                q = new node;
                p->son[a[i]]=q;
                p=q;
            }
        }
        p->num=x;
    }
    
    int Find(int x){
        int a[32];
    
        node *p=root;
        for(int i=0;i<32;i++){
            a[i]=x&1;
            x>>=1;
        }
    
        for(int i=31;i>=0;i--){
            if(p->son[!a[i]]!=NULL){
                p=p->son[!a[i]];
            }else p=p->son[a[i]];
        }
        return p->num;
    }
    
    void del(node *p){
        for(int i=0;i<2;i++)
            if(p->son[i]!=NULL) del(p->son[i]);
    
        delete(p);
    }
    
    int main(){
        int t;
        scanf("%d",&t);
        int cas=0;
        while(t--){
            root = new node;
            int n,m;
            scanf("%d%d",&n,&m);
            int x;
            for(int i=0;i<n;i++){
                scanf("%d",&x);
                Insert(x);
            }
            printf("Case #%d:
    ",++cas);
            while(m--){
                scanf("%d",&x);
                printf("%d
    ",Find(x));
            }
            del(root);
        }
        return 0;
    }
     
  • 相关阅读:
    oracle启动的三步
    Solaris下vi的简单使用帮助
    Solaris下ftp配置(初稿待补充)
    soap笔记1
    Solaris 10 查看机器的网卡mac地址
    查看表空间名称与对应文件
    [转]Ubuntu10.04的网络配置
    [转]红帽企业版RHEL6使用Fedora13的yum源
    [转]linux忘记密码怎么办法
    [转]个人管理 - IT人士书籍推荐(已读)
  • 原文地址:https://www.cnblogs.com/fht-litost/p/8684608.html
Copyright © 2011-2022 走看看