PAT--Hashing - Hard Version (30)
阿新 • • 發佈:2019-01-14
首先說一下大家最關注的吧,你是不是有兩個樣例沒過呢?
哈哈,有一個樣例可能是當在m-1處遇到衝突是,將開始從0探測,另一個樣例是我找了大半天才找出來的。廢話不說,且看下例:
10
-1 -1 13442 17453 25364 10545 27094 17117 17228 13133
正確答案是:10545 13442 17117 17228 17453 25364 27094 13133
而我的答案是10545 13442 17117 17228 13133 17453 25364 27094
不難發現,我的問題在於認為a,b,c,d,e,f,g這些非負整數中,g只要出現在f後面即可。如果輸出f,那麼就可以輸出g。但事實上,假設g和d是同餘的(mod m)那麼,g顯然必須在d,e,f都輸出之後才能輸出。
好了,這是我遇到的問題,如果沒有解決你的問題,請看最後,我寫了一個生成資料的程式碼,你可以用這個程式碼生成幾個資料,自己測一下。
本來我是很不想用拓撲排序的,沒辦法,自己的演算法失效了,還是拓撲排序咯。
這個圖怎麼建立,請參考:http://blog.sina.com.cn/s/blog_ce1b01420102vizs.html
#include<stdio.h> #include<queue> #include<vector> #include<map> using namespace std; #define N 1005 priority_queue<int,vector<int>,greater<int> > pq;//優先佇列,用以輸出可以輸出的最小值 vector<int> v[N];//記錄圖 map<int,int> reserve;//記錄某個數對應的下標 int main(){ int m,b,temp; int h[N]; int indeg[N]; int presite,nowsite; scanf("%d",&m); int i,j,size=0; for(i=0;i<m;i++){//輸入 scanf("%d",&h[i]); //reserve[h[i]]=i; reserve.insert(pair<int,int>(h[i],i)); } for(i=0;i<m;i++){//記錄圖和入度 if(h[i]<0){ indeg[i]=-1; continue; } indeg[i]=0; nowsite=i; presite=h[i]%m; if(nowsite!=presite){ while(presite!=nowsite){ v[presite].push_back(nowsite); presite=(presite+1)%m; indeg[nowsite]++; } } else{ pq.push(h[i]); indeg[i]=-1; } } bool flag=true; while(!pq.empty()){ temp=pq.top(); pq.pop(); temp=reserve[temp]; for(i=0;i<v[temp].size();i++){//殺掉temp,其指向的點入度減一 indeg[v[temp][i]]--; } for(i=0;i<m;i++){//入度為0,入隊 if(indeg[i]==0){ pq.push(h[i]); indeg[i]--; } } if(flag){//如果是第一個數,前面不加空格 printf("%d",h[temp]); flag=false; } else{ printf(" %d",h[temp]); } } return 0; }
生成資料的程式碼,可以藉助這個除錯喲!
注意,建議m取10,方便除錯,你也可以改成其他值噠
#include<stdio.h> #include<time.h> #include<memory.h> #include<stdlib.h> #define N 100000 int number[N]; int hash[1005]; int main(){ FILE *fp; fp=fopen("in2.txt","w"); if(fp==NULL){ puts("ERROR"); return -1; } int num=50,i,j,m,temp,sit,n; srand((unsigned)time(NULL)); //num控制測試總組數 while(num--){ memset(hash,-1,1005*sizeof(int)); memset(number,0,N*sizeof(int)); //m控制 第一個數 ,建議取10,方便除錯 //m=rand()%1000+1; m=10; fprintf(fp,"%d\n",m); n=1; if(m!=1) n=rand()%(m/2)+(m/2)+1; for(i=0;i<n;i++){ temp=rand()%N; while(number[temp]==1){ temp=rand()%N; } //printf("%d ",temp); number[temp]=1; sit=temp%m; while(hash[sit]!=-1){ sit=(sit+1)%m; } hash[sit]=temp; } //puts(""); for(i=0;i<m;i++){ fprintf(fp,"%d ",hash[i]); } fprintf(fp,"\n"); } return 0; }