hdu4825
来源:互联网 发布:软件开发自学 编辑:程序博客网 时间:2024/06/10 09:32
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
23 23 4 5154 14 6 5 63
Sample Output
Case #1:43Case #2:4解题思路:将给定得数按照二进制建成一颗字典树,每一层分别对应的各个位数上的01状态, 然后每一次查询,如果对应位置为0,则要往1的方向走,如果是1,则要往0的方向走。但是要注意,走的前提是对应分支是存在的。
说明:自己写的,很低级。。。
#include "stdafx.h"#include "iostream"#include <stdio.h>#include <stdlib.h>#include <string.h>using namespace std;#define MAX 2 //用二进制,每个节点最多有两个分支#define maxlen pow(2,8)-1 //二进制码的长度int *dec2Bin(int dec);//十进制转二进制int bin2Dec(int* bin);//二进制转十进制//定义字典树结构struct Trie{Trie *next[MAX];int v; //是否到达结尾的标志};Trie* createTrie(Trie *root, int *arr);//创建树int* findTrie(Trie *root, int *arr);//查找树int dealTrie(Trie* T);//删除树int main(){ int T;//数据组数 cin >> T;int *N = new int[T];//Zeus获得数数int *M = new int[T];//要询问的数int** re = new int*[T];//搜索到的结果for (int i = 0; i < T; i++){ Trie *tree = new Trie;Trie *root = new Trie;for (int m = 0;m < MAX; ++m){root->next[m] = NULL;}cin >> N[i] >> M[i];int *set=new int[N[i]]();re[i] = new int[M[i]];for (int j = 0; j < N[i]; j++){cin >> set[j];int *setBin = dec2Bin(set[j]);tree = createTrie(root, setBin);}for (int k = 0; k < M[i]; k++){ int obj;cin >> obj;int *binObj = dec2Bin(obj);int* tmp = findTrie(tree, binObj);re[i][k] = bin2Dec(tmp);}dealTrie(tree);}for (int i = 0; i < T; i++){cout << "Case #" << i + 1 << ":" << endl;for (int j = 0; j < M[i]; j++){cout << re[i][j] << endl;}}system("pause");return 0;}Trie* createTrie(Trie *root, int *arr){int len = maxlen;Trie *p = root; Trie *q = new Trie;for (int i = 0; i<len; i++){int id = arr[i];if (p->next[id] == NULL){q = (Trie *)malloc(sizeof(Trie));q->v = 1;for (int j = 0; j<MAX; j++)q->next[j] = NULL;p->next[id] = q;p = p->next[id];}else{//p->next[id]->v++;p = p->next[id];}}p->v = -1; //若为结尾,则将v改成-1表示return root;}int* findTrie(Trie *root, int *arr){Trie *p = root;int len = maxlen;int* re = new int[len]();for (int i = 0; i < len; i++){int id = arr[i];if (p->next[1 - id] != NULL)//优先选择与要查询的数这一位相反的方向{re[i] = 1 - id;p = p->next[1 - id];}else{p = p->next[id];re[i] = id;}}return re;}int dealTrie(Trie* T){int i;if (T == NULL)return 0;for (i = 0; i < MAX; i++){if (T->next[i] != NULL)dealTrie(T->next[i]);}free(T);return 0;}int* dec2Bin(int dec){int len = maxlen;int *b = new int[len]();;int i = dec;int j = 1;while (i){b[len-j] = i % 2;i = i / 2;j++;}return b;}int bin2Dec(int* bin){ int len = maxlen;int re=0;for (int i = 0; i < len; i++){re += pow(2, len - 1 - i)*bin[i];}return re;}
另外把给出的答案记录一下:
觉得大神写的太巧妙了,,,
#include "stdafx.h"#include <cstdio>#include <cstring>#include <iostream>using namespace std;//typedef __int64 ll;typedef long long ll;const int M = 55;const int N = M*1e5;struct Node {ll val;int l;int r;void clear() {l = r = -1;}}node[N];int p;ll a, t[M];void insert(int& root, int d, ll u) {//尤其注意这里的按引用调用!!!root值改变的话,node[root].l的值也改变了!!!!,并且递归到底后root=51后,要逐层返回,最后root为0if (root == -1) {root = p++;node[root].clear();}if (d == -1) {node[root].val = u;return;}if (u & t[d])insert(node[root].r, d - 1, u);elseinsert(node[root].l, d - 1, u);}void query(int root, int d, ll u) {if (d == -1) {printf("%lld\n", node[root].val);return;}if (((u & t[d]) && node[root].l != -1) || node[root].r == -1)query(node[root].l, d - 1, u);elsequery(node[root].r, d - 1, u);}int main() {//cout << sizeof(unsigned int);int cas, n, m;scanf("%d", &cas);t[0] = 1;for (int i = 1; i < 55; i++)t[i] = t[i - 1] * 2;for (int i = 1; i <= cas; i++) {p = 0;int root = -1;scanf("%d%d", &n, &m);for (int j = 0; j < n; j++) {scanf("%lld", &a);insert(root, 50, a);}printf("Case #%d:\n", i);for (int j = 0; j < m; j++) {scanf("%lld", &a);query(root, 50, a);}}return 0;}
0 0
- hdu4825
- hdu4825 字典树 + 贪心
- hdu4825字典树
- HDU4825 01trie+二进制
- hdu4825---Xor Sum(Trie + 贪心)
- Trie树 hdu4825 Xor Sum
- HDU4825 Xor Sum 字典树
- hdu4825 Xor Sum 【字典树】
- hdu4825 01字典树+贪心
- hdu4825 Xor Sum【Trie、Xor】
- hdu4825(Trie树+位运算)
- HDU4825 - Xor Sum(Trie 字典树)
- HDU4825 Xor Sum(Trie树 + 贪心)
- HDU4825 Xor Sum(Trie树,二进制)
- hdu4825 Xor Sum 字典树与异或(经典)
- 字典树(2)--hdu4825(字典树基本应用)
- hdu4825-01字典树&&贪心&&经典&&异或最大-Xor Sum
- HDU4825 Xor Sum 0-1字典树 最大异或和
- PHP字符串函数之 strstr stristr strchr strrchr
- Android_SlidingMenu开源项目_导航框架实现侧滑
- poj 备忘录
- ACM ProblemB
- USACO-Section 3.2 Feed Ratios(枚举)
- hdu4825
- MVC 与 SSH(个人总结)
- android弹出软键盘,view整体上移问题
- java 的float型数据保存到数据库中变成了整数
- ACM第一次练习—1006G
- 精准剖析白帽SEO和黑帽SEO的区别
- Java异常处理实例分析--六种异常处理的陋习
- Python学习:Flask框架和jinja2模板
- Office Word页眉页脚设置、显示分节符、页眉“与上一节相同”的问题