• 2014百度之星资格赛解题报告:Xor Sum


    Xor Sum
    时间限制: 1S     空间限制:64M
    问题描述
    Zeus 和 Prometheus 做了一个游戏,Prometheus给 Zeus 一个集合,集合中包含了N个正整数,随后 Prometheus 将向 Zeus 发起M次询问,每次询问中包含一个正整数 S ,之后 Zeus 需要在集合当中找出一个正整数 K ,使得 K 与 S 的异或结果最大。Prometheus为了让 Zeus 看到人类的伟大,随即同意 Zeus 可以向人类求助。你能证明人类的智慧么?
    输入
    输入包含若干组测试数据,每组测试数据包含若干行。
    输入的第一行是一个整数TT < 10),表示共有T组数据。
    每组数据的第一行输入两个正整数NM<1=N,M<=100000),接下来一行,包含N个正整数,代表 Zeus 的获得的集合,之后M行,每行一个正整数S,代表 Prometheus 询问的正整数。所有正整数均不超过2^32
    输出
    对于每组数据,首先需要输出单独一行”Case #?:”,其中问号处应填入当前的数据组数,组数从1开始计算。
    对于每个询问,输出一个正整数K,使得KS异或值最大。
    样例输入
    2
    3 2
    3 4 5
    1
    5
    4 1
    4 6 5 6
    3
    样例输出
    Case #1:
    4
    3
    Case #2:
    4

    解题报告
    由于每个正整数都不超过232次方,所以将每个正整数的二进制数字作为字符串插入到字典树中,对于每一个询问,只需要按照贪心的做法搜索字典树就行了。
    1. 将所有数字转为二进制。
    2. 将集合中的所有二进制数变为一棵二叉树,左节点代表这一位为0,右节点代表1
    3. 对每一个询问,在这课二叉树上查询,如果这一位为0并且右孩子不为空,则往右走,否则往走左。最终到达叶子节点经过的路径就是所求的数的二进制表示。

    解题代码:
    #include <iostream>
    #include <cstdio>
    #include <cstdlib>
    #define LENGTH 32
    #define MAXN 100000
    using namespace std;
    typedef struct node{
            node *next[2];
            bool flag;
    };
    
    node Head;
    node arr[LENGTH * MAXN];
    int nodeCount;
    
    node *GetNewNode(){
            if (nodeCount >= LENGTH * MAXN) {
                    printf("ERROR : node count full!");
                    exit(1);
            }
            arr[nodeCount].next[0] = NULL;
            arr[nodeCount].next[1] = NULL;
            arr[nodeCount].flag    = false;
            return &(arr[nodeCount++]);
    }
    
    void Init(){
            nodeCount = 0;
            Head.next[0] = NULL;
            Head.next[1] = NULL;
            Head.flag    = false;
    }
    
    void insertNode(unsigned int num){
            node *p = &Head;
            int temp;
            for (int i = LENGTH - 1; i>=0; i--){
                    if (((1<<i)&num) != 0){
                            temp = 1;
                    } else {
                            temp = 0;
                    }
                    
                    if (p->next[temp] == NULL){
                            p->next[temp] = GetNewNode();
                    }
                    
                    p = p->next[temp];
            }
            p->flag = true;
    }
    
    unsigned int searchNode(unsigned int s){
            unsigned int k;
            node *p = &Head;
            int temp;
            k = 0;
            for (int i = LENGTH - 1; i>=0 ;i--){
                    if (((1<<i)&s) != 0){
                            temp = 0;
                    } else {
                            temp = 1;
                    }
                    
                    if (p->next[temp] == NULL){
                            k = (k << 1) + (temp ^ 1);
                            p = p->next[temp ^ 1];
                    } else {
                            k = (k << 1) + temp;
                            p = p->next[temp];
                    }
            }
            return k;
    }
    
    int main(){
            int n , m ;
            unsigned int k , s;
            Init();
            int case_count = 0;
            scanf("%d", &case_count);
            int case_index = 0;
            while ((case_count--) && scanf("%d%d" , &n , &m) != EOF){
                    case_index++;
                    printf("Case #%d:
    ", case_index);
                    Init();
                    for (int i = 0; i < n; i++){
                            scanf("%u",&k);
                            insertNode(k);
                    }
                    for (int i = 0; i < m; i++){
                            scanf("%u" , &s);
                            k = searchNode(s);
                            printf("%u
    " , k);
                    }
            }
            return 0;
    }


  • 相关阅读:
    64_l2
    64_l1
    64_k2
    64_k1
    64_j2
    64_j1
    64_g6
    64_g5
    64_g4
    64_g3
  • 原文地址:https://www.cnblogs.com/hosealeo/p/4190533.html
Copyright © 2020-2023  润新知