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;
}