[PTA] hashing( hard version)

  一开始以为是普通的数学计算题,思考了很久也没有结果。

  当时脑中也只有一个想法——对于输入数据x,如果 x [i] % num ! = i (直接由哈希函数得到的下标值与实际下标值不相等),意味着产生了冲突,那么,下标值为 x[i]%num ~ i -1的数字,一定在x[i]之前被插入 。

  但是除此之外,我再也想不到还有什么可以得到的信息,所得到的仅仅只有不同数据的关系。所以我的本能反应是先建了一个数组bool b[MAX][MAX],其中 b[i][j] 代表 a[i] 是否必须在 a[j] 之前出现 ,然后写了一个重载cmp函数,利用sort对原数据按照特定的顺序进行重排列。

  其实看到这样的关系(事物完成的顺序性),已经怀疑这道题涉及到图论拓扑排序那边的知识,后来去pta网上看了一下,这道题果然归类在拓扑排序下。有了明确的方向后,又继续开始整理思路。

  拓扑排序本身是很简单的,只是在这题是多解题,它对输出解也有了限制,要求在多解中选择key值最小的值优先输出,这就增加了题目的难度。拓扑排序有基于深度优先搜索的,也有基于广度优先搜索的,后者和入度有着关联,而后者也是我用的最多的。

  广度优先搜索的核心就是先将一部分点放到某个容器,然后再弹出点,并放入与它有关联的点,直到容器为空。在这里,这种关联就是之前的 b[MAX][MAX],也就是是否存在顺序性。而题目中又要求最小值,就很容易想到了应该是用最小堆来作为这个容器,每次取出的点都是当前容器中的最小值。

  计算图中每个点的入度,入度为0就代表着这个数的插入不存在冲突,为x则代表冲突了x次。而前面提到的“先将一部分点放到某个容器”就是先将不存在冲突的点放入容器。弹出点的时候,也就输出了结果,这个点从图中被拿出,与之关联的点的入度也随之减少,也就是说,这个数值已经插入了,和它相关的点(需要在它后面输出的点)就没有什么好担心的了,当这种关联影响(入度)减少为0时,就可以被放入容器了。


  为了省事,用了stl中的优先队列(最小堆):

#include<stdio.h>
#include<stdlib.h>
#include<queue>
#define MAX 1000

using namespace std;

struct node{
	int x;
	int i;
	bool operator<(const node w)const{
		return x>w.x;
	}
};

int ans[1000];
bool b[1000][1000];//b[i][j]代表a[i]是否必须在a[j]之前出现 
int num;
int cnt=0;
int indegree[1000];
node a[1000];

void TopSort()
{
	priority_queue<node>q;
    for(int i=0;i<num;i++){
        if(indegree[i]==0){
        	q.push(a[i]);
        }
    }
    while(!q.empty()){
    	node v=q.top();
    	ans[cnt++]=v.x;
        q.pop();
        for(int j=0;j<num;j++){
            if(b[v.i][j]){
            	if(--indegree[j]==0){
            		q.push(a[j]);
            	}
            }
        }
   } 
}

int main()
{

	int i,j;
	scanf("%d",&num);
    for(i=0;i<num;i++){
    	scanf("%d",&a[i].x);
    	a[i].i=i;
    	indegree[i]=0;
    	for(j=0;j<num;j++){
    		b[i][j]=false;
    	}
    }
	for(i=0;i<num;i++){
		if(a[i].x==-1){
			indegree[i]=-1;
			continue;
		}
		indegree[i]=(i-a[i].x%num+num)%num;
		for(j=a[i].x%num;j!=i;j=(j+1)%num){
			b[j][i]=true;
		}
	}
	TopSort();
	for(i=0;i<cnt-1;i++)printf("%d ",ans[i]);
	printf("%d",ans[cnt-1]);
	return 0;
}


你可能感兴趣的:([PTA] hashing( hard version))