7-18 Hashing

7-18 Hashing - Hard Version (30 分)

Given a hash table of size 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.

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.

知识点:

拓扑排序

priority_queue的用法:

  • priority_queue<int,vector<int>,greater<int> > q; 建立小顶堆
  • priority_queue<int,vector<int>,less<int> > q; 建立大顶堆

map 的一些用法:

  • 遍历一个 map  
    for(map<int,int>::iterator it=mp.begin();it!=mp.end();it++){ if(list[it->second]==0){ q.push(it->first); } }

思路:

这是一个拓扑排序问题。建立一个优先队列(最小堆)。寻找所有元素,将入度为0的入队,然后将所有以它为前置节点的项,入度都减1。

入度的计算:考虑到是线性探测,每个元素的入度就是(它目前在的位置 - 应该在的位置),如负,加hash表长。

用 map 建立每个数的索引,不然空间不够。

 1 #include <iostream>
 2 #include <cmath>
 3 #include <queue>
 4 #include <vector>
 5 #include <map>
 6 using namespace std;
 7 const int maxn = 1005;
 8 int n;
 9 int a[maxn];
10 vector<int> zu[maxn];
11 priority_queue<int,vector<int>,greater<int> > q;
12 int list[maxn];
13 map<int,int> mp;
14 
15 int main(){
16     scanf("%d",&n);
17     fill(list,list+maxn,-1);
18     for(int i=0;i<n;i++){
19         scanf("%d",&a[i]);
20         if(a[i]<=-1) continue;
21         mp[a[i]] = i;
22         list[i] = i-a[i]%n;
23         if(list[i]<0) list[i]+=n;    
24     }
25     for(int i=0;i<n;i++){
26         if(a[i]<=-1) continue;
27         int j=a[i]%n;
28         while(j!=i){
29             zu[mp[a[j]]].push_back(a[i]);
30             j+=1;
31             if(j>=n) j-=n;
32         }
33     }
34         for(map<int,int>::iterator it=mp.begin();it!=mp.end();it++){
35         if(list[it->second]==0){
36             q.push(it->first);
37         }
38     }
39     //printf("12 %d
",list[12]);
40     vector<int> out;
41     while(q.size()){
42         int tmp = q.top();
43         q.pop();
44         out.push_back(tmp);
45         for(int i=0;i<zu[mp[tmp]].size();i++){
46             list[mp[zu[mp[tmp]][i]]]--;
47             //printf("32: %d
",list[mp[32]]);
48             if(list[mp[zu[mp[tmp]][i]]]==0){
49                 q.push(zu[mp[tmp]][i]);
50             }
51         }
52     }
53     for(int i=0;i<out.size();i++){
54         if(i!=0) printf(" ");
55         printf("%d",out[i]);
56     }
57 }

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

原文地址:https://www.cnblogs.com/lokwongho/p/9851968.html