PTA_2019春_Hashing - Hard Version

博客围绕从给定哈希表状态重构输入序列的问题展开,介绍了哈希函数及线性探测解决冲突的情况,给出输入输出规格说明,还提到一开始未意识到是拓扑排序问题,可从冲突数(入度)计算,计算公式为(i - key%tablesize + tablesize)%tablesize。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Given a hash table of size N, we can define a hash function H(x)=x%N. 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.

Input Specification:

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.

Output Specification:

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.

Sample Input:

11
33 1 13 12 34 38 27 22 32 -1 21

Sample Output:

1 13 12 21 33 34 38 27 22 32

 一开始并没有想到这是一个拓扑排序的问题,看了别人的分析才意识到。

从冲突数出发,即入度。计算公式为(i-key%tablesize+tablesize)%tablesize

/*拓扑排序*/
#include<stdio.h>
#include<stdlib.h>
struct heapnode {
	int* data;   /*存储数据的数组*/
	int size;    /*当前元素个数*/
	int capacity;  /*容量*/
};
typedef struct heapnode* Heap;
Heap createheap(int maxsize) {
	Heap H = (Heap)malloc(sizeof(struct heapnode));
	H->data = (int*)malloc((maxsize + 1) * sizeof(int));
	H->capacity = maxsize;
	H->size = 0;
	H->data[0] = -20000;
	return H;
}
void insert(Heap H, int x) {
	int i;
	H->size++;
	i = H->size; /*i指向将要插入的位置*/
	for (; H->data[i / 2] > x; i /= 2) {
		H->data[i] = H->data[i / 2];
	}
	H->data[i] = x;
}
int deletemin(Heap H) {
	int parent, child;
	int  x;
	int min = H->data[1];
	x = H->data[H->size--];
	for (parent = 1; parent * 2 <= H->size; parent = child) {
		child = parent * 2;
		if ((child != H->size) && (H->data[child] >H->data[child + 1])) {
			child++;
		}
		if (x<= H->data[child])break;
		else {
			H->data[parent] = H->data[child];
		}
	}
	H->data[parent] = x;
	return min;
}
int isempty(Heap H) {
	return (H->size == 0);
}
int hash(int key,int N) {   /*本来应该插入的位置*/
	return key % N;
}
int Indegree(int i, int key, int N) {
	return (i - key % N + N) % N;
}
int find(int *array,int N,int key) {
	for (int i = 0; i < N; i++) {
		if (array[i] == key)  return i;
	}
}
int main() {
	int N;
	scanf("%d", &N);
	int temp;
	int* array = (int*)malloc(N * sizeof(int));
	int* indegree = (int*)malloc(N * sizeof(int));
	for (int i = 0; i < N; i++) {
		indegree[i] = -1;
	}
	int ab[1001][1001];
	for (int i = 0; i < 1001; i++) {
		for (int j = 0; j < 1001; j++) {
			ab[i][j] = 0;
		}
	}
	Heap H = createheap(N);
	for (int i = 0; i < N; i++) {
		scanf("%d", &temp);
		array[i] = temp;
		if (temp >= 0) {
			int a = hash(temp, N);
			indegree[i] = Indegree(i, temp, N);      /*获得每个点的冲突数,即入度*/
			if (indegree[i] == 0) {  /*入堆*/
				insert(H, temp);
			}
			else if (indegree[i] > 0) {
				for (int j = 0; j <= indegree[i]; j++) {
					int k = hash(a + j, N);
					ab[k][i] =1;
				}
			}
		}
	
	}
	int min;
	int flag = 0;
	int place;
	while (isempty(H) == 0) {
		min = deletemin(H);
		if (flag == 1) printf(" ");
		printf("%d", min);
		flag = 1;
		place = find(array, N, min);
		for (int i = 0; i < N; i++) {
			if (ab[place][i] ==1) {
				indegree[i]--;
				if (indegree[i] == 0) {
					insert(H, array[i]);
				}
			}
		}
	}
	return 0;
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值