hdoj4825 Xor Sum

题目:

Problem Description
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

很明显,直接暴力求该值与数组中的值的异或然后比较大小肯定过不了。
由于异或运算是位运算,因此这道题可以将这些数字转换为二进制数,二进制数只有0或1,而异或出来的值如果为1,则它越靠近高位,最终异或的结果越大。因此,我们可以用字典树维护。

异或是相同为0,不同为1,因此在对要查询的数进行处理时,该位为1则变为0,该位为0则变为1.

高位不足则补0.
这道题虽然是字典树,但是要处理的细节很多,这道题也不算简单。

参考代码:

#include <iostream>
#include <cstring>
#include <algorithm>
#include <stack>
#include <map>
#include <vector>
#include <cmath>
using namespace std;
const int N = 100000+10;
typedef long long LL;

struct Trie {
    LL f;
    Trie *next[2];//0 and 1;
};

Trie *root;

int a[35];//保存数字转换为二进制之后的每一位数;

void change(LL num) {
    int i = 0;
    while (num) {
        a[i++] = num % 2;
        num = num / 2;
    }
} 

void createTrie(int a[]) {
    Trie *p = root, *q;
    int len = 34;//高位靠近树根;
    while (len >= 0) {
        int id = a[len];
        if (p->next[id] == NULL) {
            q = new Trie();
            for (int i = 0;i < 2;++i) {
                q->next[i] = NULL;  
            }
            p->next[id] = q;
            p = p->next[id];
        }
        else {
            p = p->next[id];
        }
        if (id) p->f = (LL) (1) << len;//如果下标为1, 表明该权重有值;
        --len;  
    }
}

LL findTrie(int a[]) {
    Trie *p = root;
    int len = 34;
    LL ans = 0;
    while (len >= 0) {
        int id = a[len];

        if (p->next[id] == NULL) {//所有的数字的二进制数都没有以id值为最高位;
            id = id ^ 1;
        }

        p = p->next[id];
        if (id) {
            //cout << s.size() << " " << id << endl;
            ans += p->f;    
        }
        --len;
    }
    return ans;
}

int main() {
    ios::sync_with_stdio(false);
    cin.tie(NULL);

    int t;
    cin >> t;
    for (int cnt = 1;cnt <= t;++cnt) {
        root = new Trie();
        root->next[0] = NULL;
        root->next[1] = NULL;
        
        int n, m;
        cin >> n >> m;
        LL number;
        for (int i = 1;i <= n;++i) {
            cin >> number;
            memset(a, 0, sizeof(a));//初始化;
            change(number);
            createTrie(a);
        }
        
        int query;
        cout << "Case #" << cnt << ":" << endl;
        for (int i = 1;i <= m;++i) {
            cin >> query;
            memset(a, 0, sizeof(a));
            change(query);
            for (int i = 0;i < 35;++i) {
                a[i] = a[i] ^ 1;//转换;//两数异或, 不相同为1, 这里转换后就变为相同为1;
            }
            LL ans = findTrie(a);
            cout << ans << endl;
        }
        
        delete root;
    }
    return 0;
}
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 211,884评论 6 492
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,347评论 3 385
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 157,435评论 0 348
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,509评论 1 284
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,611评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,837评论 1 290
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,987评论 3 408
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,730评论 0 267
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,194评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,525评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,664评论 1 340
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,334评论 4 330
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,944评论 3 313
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,764评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,997评论 1 266
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,389评论 2 360
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,554评论 2 349

推荐阅读更多精彩内容