11-散列4 Hashing - Hard Version

    xiaoxiao2022-07-03  102

     算法思想:

    这道题也是做到哭:。

    方法一:先是用数组A记录冲突数,扫描一遍散列表,将冲突数为0的数放入数组B中,每输出B中一个最小数后将其H(key)相同的数的冲突数减1,然后重复,这个方法是在手工模拟了大半个小时后摸出来的规律。然后测试点4最大N死活过不去,超时(全程暴力破解,不超时才怪)。

    方法二:然后实在不行了,看了姥姥的解说,用拓扑排序,然而又不是普通的拓扑排序,按要求要从小到大的原则输入,要在输出一个目前入度为0数组中最小值,然后将剩下所有入度为0的数再排序一次,再重复②,直至输出数等于输入中不是负数的个数。

    题目和代码段在下方(仅供参考):

    中国大学MOOC-陈越、何钦铭-数据结构-2019春

    11-散列4 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 21

    Sample Output:

    1 13 12 21 33 34 38 27 22 32

     代码段1:

    /***************2019.5.21-09:20-12:00**************/ //11-散列4 Hashing - Hard Version V1.0(最大N超时) 目测是暴力法超时 #include<stdio.h> #include<algorithm> #include<string.h> using namespace std; typedef struct HashNode *Hash; struct HashNode{ int key; int H_key; int Coll;//collision }; int main(){ int i,j; int N; scanf("%d",&N); Hash H=(Hash)malloc(N*sizeof(struct HashNode)); for(i=0;i<N;i++){ scanf("%d",&H[i].key); H[i].H_key=H[i].key%N; if(H[i].key>=0){ H[i].Coll=i-H[i].H_key; if(H[i].Coll<0) H[i].Coll+=N; } else H[i].Coll=-1; } int k=0,In[N],Mark[N]; memset(Mark,0,sizeof(Mark)); for(j=0;j<N;j++){ //遍历散列表,将coll==0的加入In数组 if(H[j].Coll==0){ In[k]=H[j].key; H[j].Coll=-1; k++; } } // printf("k=%d\n",k); // for(i=0;i<k;i++) printf("k[%d]=%d\n",i,In[i]); int l=0,cnt=0; for(i=0;;i++){ if(k>l){ sort(In+l,In+k); Mark[In[l]%N]=1; l++; } cnt=0; for(j=0;j<N;j++){ // 遍历散列表,将coll==0的加入In数组 if(Mark[H[j].H_key]==1){ H[j].Coll--; if(H[j].Coll==0) { In[k++]=H[j].key; } } if(H[j].Coll<0) cnt++; } if(cnt==N) break; } for(i=0;i<k;i++){ printf("%d",In[i]); if(i<k-1) printf(" "); else printf("\n"); } return 0; }

    代码段2:

    /***************2019.5.21-09:20-12:00**************/ /***************2019.5.22-08:30-12:10 (V2.0)**************/ //11-散列4 Hashing - Hard Version V1.0(最大N超时) 目测是暴力法超时 V2.0改用拓扑排序,ok 共6h #include<stdio.h> #include<algorithm> #include<string.h> using namespace std; typedef struct LNode *List; struct LNode{ int Index; List Next; }; struct GNode{ int Data; int InD; List First; }G[1008]; bool cmp(int a,int b){ if(G[a].Data>G[b].Data) return 0; else return 1; } int main(){ int i,j; int N; scanf("%d",&N); int key,H_key,cnt=0; for(i=0;i<N;i++) G[i].First=NULL; for(i=0;i<N;i++){ scanf("%d",&key); G[i].Data=key; if(key>=0){ cnt++; H_key=key%N; G[i].InD=(i-H_key+N)%N; if(G[i].InD>0){ for(j=H_key;j!=i;j=(j+1)%N){ List X=(List)malloc(sizeof(struct LNode)); X->Index=i; X->Next=G[j].First; G[j].First=X; } } } else G[i].InD=-1; } // for(i=0;i<N;i++){ // printf("%d->",G[i].Data); // List X=G[i].First; // while(X){ // printf("%d->",G[X->Index].Data); // X=X->Next; // } // printf("\n"); // } // printf("cnt=%d\n",cnt); int In[cnt],k=0,l=0; for(i=0;i<N;i++){ if(G[i].InD==0) In[k++]=i; } sort(In,In+k,cmp);//以防全部InD都是0的情况 int Pre_k=0; while(k<cnt){ List X=G[In[l]].First; l++; while(X){ G[X->Index].InD--; if(G[X->Index].InD==0) In[k++]=X->Index; X=X->Next; } if(k>Pre_k){ sort(In+l,In+k,cmp); Pre_k=k; } // printf("k=%d:",k); // for(i=0;i<k;i++) printf("In[%d]=%d ",i,In[i]); // printf("\n"); } for(i=0;i<cnt;i++){ printf("%d",G[In[i]].Data); if(i<cnt-1) printf(" "); else printf("\n"); } return 0; }

     

    最新回复(0)