09-散列3. Hashing - Hard Version (30)
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 21Sample Output:
1 13 12 21 33 34 38 27 22 32
主要思路:
哈希表规模为n。对于输入的位置编号为i的元素a,如果:
1.i==a%n。说明a放i位置不是由于冲突,将a放入优先队列。
2.i>a%n。如果编号为a%n到n-1的元素之前已经填入哈希表(h1[j].exist=true),则第i个元素可以进入优先队列。否则,如果编号为a%n到n-1的元素在位置编号为i的元素填入之后填入哈希表,意味着位置编号为i的元素插入哈希表时,发生冲突向后转移不可能到达位置i,而应该在i位置之前填入,矛盾。
3.i<a%n。与2同理。
1 #include<cstdio> 2 #include<algorithm> 3 #include<iostream> 4 #include<cstring> 5 #include<queue> 6 using namespace std; 7 struct node{ 8 bool exist; 9 node(){ 10 exist=false; 11 } 12 }; 13 node h1[1005]; 14 priority_queue< pair<int,int>,vector<pair<int ,int> >,greater<pair<int,int> > > pq;//记录值和放的位置,按pair的第一个元素升序排列 15 pair<int,bool> input[1005];//标记元素有没有进入队列 16 queue<int> q; 17 int main(){ 18 //freopen("D:\\INPUT.txt","r",stdin); 19 int n,num,i,count=0; 20 scanf("%d",&n); 21 for(i=0;i<n;i++){ 22 scanf("%d",&num); 23 input[i]=make_pair(num,false); 24 if(num>=0){//记录不等于负数的元素个数 25 count++; 26 } 27 } 28 int j,k,post; 29 for(i=0;i<count;i++){//复杂度n^2:扫数列count次,每次将当前满足条件的最小元素进入队列q 30 for(j=0;j<n;j++){//遍历数列的每个元素 31 if(!input[j].second&&input[j].first>=0){//寻找没有进入队列并且不等于-1的元素 32 post=input[j].first%n;//元素本来应该在哈希表中的位置 33 if(post==j){//本来要放的位置和现在在哈希表中的位置相同 34 pq.push(make_pair(input[j].first,j)); 35 //h1[post].exist=true;//标记 36 input[j].second=true; 37 continue; 38 } 39 if(post<j){//本来要放的位置在现在的位置前面 40 for(k=post;k<j;k++){ 41 if(!h1[k].exist){//前面没有元素填充 42 break; 43 } 44 } 45 if(k==j){//可以进队pq 46 pq.push(make_pair(input[j].first,j)); 47 //h1[j].exist=true; 48 input[j].second=true; 49 } 50 } 51 else{//post>j 52 for(k=post;k<n;k++){//先由post开始向后遍历 53 if(!h1[k].exist){ 54 break; 55 } 56 } 57 if(k==n){//满足条件后,由0开始向j遍历 58 for(k=0;k<j;k++){ 59 if(!h1[k].exist){ 60 break; 61 } 62 } 63 if(k==j){ 64 pq.push(make_pair(input[j].first,j)); 65 //h1[j].exist=true; 66 input[j].second=true; 67 } 68 } 69 } 70 } 71 } 72 pair<int,int> top=pq.top(); 73 pq.pop(); 74 q.push(top.first);//找到本次满足条件:在队列pq且最小的元素,进入输出队列q 75 h1[top.second].exist=true;//意味着top.second位置已经放了元素 76 } 77 printf("%d",q.front());//对输出队列q进行输出 78 q.pop(); 79 while(!q.empty()){ 80 printf(" %d",q.front()); 81 q.pop(); 82 } 83 return 0; 84 }