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
原创粉丝点击