HDU 4825 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 #include <iostream>
 2 #include <string.h>
 3 #include <stdio.h>
 4 #include <stdlib.h>
 5 const int N = 100010;
 6 
 7 struct Nod {
 8     int id;
 9     Nod *next[2];
10     Nod() {
11         next[0] = next[1] = NULL;
12         id = 0;
13     }
14 };
15 int t, n, m, x, cas;
16 void mkTree(Nod *root,int x) {
17     Nod *p = root;
18     for(int i = 31; i >= 0; i --) {
19         int a = (x>>i)&1;
20         if(p->next[a] == NULL) p->next[a] = new Nod;
21         p = p->next[a];
22     }
23     p->id = x;
24 }
25 int find(Nod *root,int x) {
26     Nod *p = root;
27     for(int i = 31; i >= 0; i --) {
28         int a = (x>>i)&1;
29         if(p->next[a^1] != NULL) p = p->next[a^1];
30         else p = p->next[a];
31     }
32     return p->id;
33 }
34 void dele(Nod *p) {
35     for(int i = 0; i < 2; i ++) {
36         if(p->next[i])
37             dele(p->next[i]);
38     }
39     free(p);
40     return;
41 }
42 int main() {
43     scanf("%d", &t);
44     while(t--) {
45         Nod *root = new Nod;
46         scanf("%d %d", &n, &m);
47         for(int i = 1; i <= n; i ++) {
48             scanf("%d", &x);
49             mkTree(root,x);
50         }
51         printf("Case #%d:\n",++cas);
52         while(m--) {
53             scanf("%d", &x);
54             printf("%d\n",find(root,x));
55         }
56         dele(root);
57     }
58     return 0;
59 }

 

数组:

 1 #include <stdio.h>
 2 #include <string.h>
 3 using namespace std;
 4 const int N = 3500005;
 5 int sz, tree[N], sum[N][2];
 6 
 7 void mkTree(int x) {
 8     int root = 0;
 9     for(int i = 31; i >= 0; i --) {
10         int a = (x>>i)&1;
11         if(!sum[root][a]) sum[root][a] = sz++;
12         root = sum[root][a];
13     }
14     tree[root] = x;
15 }
16 int find(int x) {
17     int root = 0;
18     for(int i = 31; i >= 0; i --) {
19         int a = (x>>i)&1;
20         if(sum[root][a^1]) root = sum[root][a^1];
21         else root = sum[root][a];
22     }
23     return tree[root];
24 }
25 int main() {
26     int t, n, m, x, cas = 1;
27     scanf("%d", &t);
28     while(t--) {
29         sz = 1;
30         memset(sum, 0, sizeof(sum));
31         memset(tree, 0, sizeof(tree));
32         scanf("%d %d", &n, &m);
33         while(n--) {
34             scanf("%d", &x);
35             mkTree(x);
36         }
37         printf("Case #%d:\n", cas++);
38         while(m--) {
39             scanf("%d", &x);
40             printf("%d\n",find(x));
41         }
42     }
43     return 0;
44 }

 

posted @ 2017-08-06 18:03  starry_sky  阅读(216)  评论(0编辑  收藏  举报