CSU-ACM2017暑假集训比赛8 - A - Xor Sum - HDU - 4825
2017-08-26 23:17
405 查看
A - Xor Sum
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
对于这题,人类的智慧就是字典树。题中的“异或”让人很容易地想到利用数的二进制形式来解决这一题。具体方法也简单:将样例数字按位取反,与模式数字比较,和取反结果相比契合程度最高的模式数字就是所求结果(异或后得到的1最多)。例如模式数字 3 4 5,它们的32位二进制数位分别为
00000000 00000000 00000000 00000011(2)00000000 00000000 00000000 00000100(2)00000000 00000000 00000000 00000101(2)
对样例数字 1 来说,对它按位取反得到
11111111 11111111 11111111 11111110(2)
可以看出,~1 (1取反后)的二进制数与 4 的二进制数契合度最高,只有它们拥有两个共同的二进制位(低位第一位、低位第三位)。显然,契合程度最高的两个数异或后得到的结果是最大的。
为实现上述比较,只需要使用长度为32个元素的数组记录模式数字和样例数字的二进制形式;将模式数字的二进制数组当成字符串,建立字典树,叶节点保存该子树对应的十进制数,再将模式数组代入字典树,能同步下行则同步下行,不能同步下行则行至另一分支。重复这个过程,走到叶节点,提取模式数字的十进制形式即得答案。
#include <cstdio> #include <iostream> #include <cstring> using namespace std; const int maxNode = 33e5, sigma_size = 2; int ch[maxNode][sigma_size]; int val[maxNode]; struct Trie{ int sz; Trie(){ sz = 1; memset(ch[0], 0, sizeof(ch[0])); } int idx(char c){ return c - 'a'; } void insert(char *s, int v){ int u = 0, n = 32; for(int i = 0; i < n; i++){ int c = s[i]; if(!ch[u][c]){ memset(ch[sz], 0, sizeof(ch[sz])); val[sz] = 0; ch[u][c] = sz++; } u = ch[u][c]; } val[u] = v; } int query(char *s){ int u = 0, n = 32; for(int i = 0; i < n; i++){ int c = s[i]; if(ch[u][c]) u = ch[u][c]; else u = ch[u][!c]; } return val[u]; } }; int main(){ #ifdef TEST freopen("test.txt", "r", stdin); #endif int Case = 1, N, M; cin >> N; while(cin >> N >> M){ Trie Td; unsigned int x; for(int i = 0; i < N; i++){ scanf("%d", &x); int memoryX = x; char pattern[32]; memset(pattern, 0, sizeof(pattern)); int pos = 31; while(x){ pattern[pos--] = x&1; x >>= 1; } Td.insert(pattern, memoryX); } printf("Case #%d:\n", Case++); for(int i = 0; i < M; i++){ scanf("%d", &x); x = ~x; char text[32]; int pos = 31; while(x){ text[pos--] = x&1; x >>= 1; } printf("%d\n", Td.query(text)); } } return 0; }
相关文章推荐
- CSU-ACM2017暑假集训比赛7 - E - Courses - HDU - 1083
- CSU-ACM2017暑假集训比赛8 - E - Escape - HDU - 3605
- CSU-ACM2017暑假集训比赛1 A - I Can Guess the Data Structure! -uva111995
- CSU-ACM2017暑假集训比赛1 C - Gourmet and Banquet CodeForces - 589F
- CSU-ACM2017暑假集训比赛2 E - ( ̄▽ ̄)/
- CSU-ACM2017暑假集训比赛2 HDU - 1597 find the nth digit
- CSU-ACM2017暑假集训比赛1 C - Gourmet and Banquet
- CSU-ACM2017暑假集训比赛7 - D - Bicoloring - UVA - 10004
- CSU-ACM2017暑假集训比赛3D - D CodeForces - 557C
- CSU-ACM2017暑假集训比赛1 TD POJ3111
- CSU-ACM2017暑假集训比赛2 B - : )
- CSU-ACM2017暑假集训比赛8 - C - GCD Table - CodeForces - 582A
- CSU-ACM2017暑假集训比赛1 B - R2D2 and Droid Army
- CSU-ACM2017暑假集训比赛1 C - Gourmet and Banquet
- CSU-ACM2017暑假集训比赛2 D - ^(●゚∀゚○)ノ
- CSU-ACM2017暑假集训比赛2 A - _(:з」∠)_
- CSU-ACM2017暑假集训比赛8 - B - The Two Routes - CodeForces - 601A
- R2D2 and Droid Army--CSU-ACM2017暑假集训比赛1
- CSU-ACM2017暑假集训比赛2 C - (╯°口°)╯(┴—┴
- CSU-ACM2017暑假集训比赛2 CodeForces - 724D