1. 程式人生 > >2014 百度之星 1003 題解 Xor Sum

2014 百度之星 1003 題解 Xor Sum

dsm xor 難題 ane rac pro 數據包 20px weight

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


看起來非常easy的題目,由於使用暴力法的代碼非常easy,可是這道題使用暴力法超時,所以就成為難題了。

題目應該使用Trie數據結構去解。並且是Trie的基本構建和搜索了。

和一般的Trie不同,就是不用26個分支了,這裏僅僅有兩個分支,那麽就更加簡單了。


我一直都不太喜歡杭電的OJ。就是由於他們的輸入輸出感覺不夠智能。尾部多個換行符或者少個換行符都不成,一般OJ都無論這個推斷答案的了。

並且本題使用自家寫的IO也不行,浪費我不少時間。


我這道題是從高位到低位構建Trie的。也是從高位到低位搜索。並且樹高是固定33. 搜索效率接近常數.

以下是收拾過的代碼。帶上釋放內存,形成良好的編程習慣。

#include <stdio.h>
#include <stdlib.h>
#include <bitset>
using std::bitset;

class XorSum1003_4
{
	struct Node
	{
		Node *children[2];
		explicit Node()
		{
			children[0] = NULL;
			children[1] = NULL;
		}
		~Node()
		{
			if (children[0]) delete children[0];
			if (children[1]) delete children[1];
		}
	};
	struct Tree
	{
		Node *emRoot;
		Tree()
		{
			emRoot = new Node;
		}
		~Tree()
		{
			if (emRoot) delete emRoot;
		}
	};

	Tree *trie;
	void insertNode(long long n)
	{
		bitset<33> bs = n;
		Node *pCrawl = trie->emRoot;
		for (int i = 32; i >= 0 ; i--)
		{
			if (!pCrawl->children[bs[i]])
			{
				pCrawl->children[bs[i]] = new Node;
			}
			pCrawl = pCrawl->children[bs[i]];
		}
	}

	long long serachXor(long long n)
	{
		bitset<33> bs = n;
		bitset<33> ans;
		Node *pCrawl = trie->emRoot;
		for (int i = 32; i >= 0 ; i--)
		{
			if (bs[i])
			{
				if (pCrawl->children[0])
				{
					ans[i] = 0;
					pCrawl = pCrawl->children[0];
				}
				else
				{
					ans[i] = 1;
					pCrawl = pCrawl->children[1];
				}
			}
			else
			{
				if (pCrawl->children[1])
				{
					ans[i] = 1;
					pCrawl = pCrawl->children[1];
				}
				else
				{
					ans[i] = 0;
					pCrawl = pCrawl->children[0];
				}
			}
		}
		return ans.to_ullong();
	}
public:
	XorSum1003_4() : trie(NULL)
	{
		int T, N, M;
		scanf("%d", &T);
		for (int i = 1; i <= T; i++)
		{
			if (trie) delete trie;
			trie = new Tree;

			printf("Case #%d:\n", i);

			scanf("%d %d", &N, &M);
			long long a, b;
			for (int k = 0; k < N; k++)
			{
				scanf("%I64d", &a);
				insertNode(a);
			}
			for (int k = 0; k < M; k++)
			{
				scanf("%I64d", &a);
				b = serachXor(a);
				printf("%I64d\n", b);
			}
		}
	}
	~XorSum1003_4()
	{
		if (trie) delete trie;
	}
};



2014 百度之星 1003 題解 Xor Sum