PTA 11-散列4 Hashing - Hard Version(详解)

11-散列4 Hashing - Hard Version(30 分)

题目地址:11-散列4 Hashing - Hard Version(30 分)

题目描述:

Given a hash table of size N N N, we can define a hash function . Suppose that the linear probing is used to solve collisions, we can easily obtain the status of the hash table with a given sequence of input numbers.
However, now you are asked to solve the reversed problem: reconstruct the input sequence from the given status of the hash table. Whenever there are multiple choices, the smallest number is always taken.


  • 输入格式
    Each input file contains one test case. For each test case, the first line contains a positive integer N (≤1000), which is the size of the hash table. The next line contains N integers, separated by a space. A negative integer represents an empty cell in the hash table. It is guaranteed that all the non-negative integers are distinct in the table.

  • 输出格式
    For each test case, print a line that contains the input sequence, with the numbers separated by a space. Notice that there must be no extra space at the end of each line.


解题方法:
最后还是参考了别人的写法,这道题主要是通过拓扑排序和优先级队列(实际上也就是最小堆)来解决。
可以通过计算冲突数来决定入度。如果冲突数为3,那么也就是说在当前位置的元素插入之前,该位置前面的3个位置必须先有元素才行,这样也就引申出当前元素的入度为3。每当前面的元素输出一个,就把他从优先级队列中去除同时把当前元素的入度-1,当有新的元素入度为0时,在插入优先队列。

易错点
题目中说空位用负数表示,且不唯一。所以在判断空位的条件是>=0。之前没注意,看了好久都没找出错误。


程序:

#include 
#include 
#include 
#include 
using namespace std;
int Arr[1001];

int ConflictTimes(int i, int key, int tablesize)
{	/* 计算每一个结点的冲突次数 */
	return (i - key%tablesize + tablesize) % tablesize;
}

int Hash(int key, int tablesize)
{	/* 计算初始映射位置 */
	return key % tablesize;
}

struct cmp
{	/* 比较函数 小顶堆 */
	bool operator() (int i, int j)
	{
		return Arr[i] > Arr[j];
	}
};

int main(int argc, char const *argv[])
{
	int N, x, flag = 0;
	scanf("%d", &N);
	int Indegree[N];
	vector <vector<int> > v(N);
	priority_queue<int, vector<int>, cmp> q;
	for (int i = 0; i < N; i++)
	{	/* 计算每一个值的冲突次数也即入度 */
		scanf("%d", &x);
		Arr[i] = x;
		if (x >= 0)	/* 跳过空位 */
		{
			int pos = Hash(x, N);
			Indegree[i] = ConflictTimes(i, x, N);
			if (Indegree[i]) /* 如果入度不是0 */
				for (int j = 0; j <= Indegree[i]; j++)
					v[Hash(pos+j, N)].push_back(i);
			else	/* 如果入度为0则直接放入优先级队列 */
				q.push(i);
		}
	}
	while (!q.empty())
	{	/* 如果队列不空,每次取队头元素,并将以队头元素为前驱的元素入度-1 */
		int pos = q.top();
		q.pop();
		if (flag == 1)
			printf(" ");
		printf("%d", Arr[pos]);
		flag = 1;
		for (int k = 0; k < v[pos].size(); k++)
			if (--Indegree[v[pos][k]] == 0)
				q.push(v[pos][k]);
		
	}
	return 0;
}

如果对您有帮助,帮忙点个小拇指呗~

你可能感兴趣的:(PTA)