PAT--Hashing - Hard Version (30)

首先說一下大家最關注的吧,你是不是有兩個樣例沒過呢?

哈哈,有一個樣例可能是當在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;
}




發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章