
输入样例:
11
33 1 13 12 34 38 27 22 32 -1 21
输出样例:
1 13 12 21 33 34 38 27 22 32
题意:根据hash得到的结果,得出输入序列
/*每个值本来应该在hash得到的下标,但因为存在冲突,所以有的会有hash值有距离
这个距离可能是hash一样的占了,也可能是hash不一样的但在前面输入的占了导致后移
*/
#include<stdio.h>
struct node{
int in; //入度,记录与本来应该的位置差多远,相关地方走一个之后-1,为0即可输出
int root; //根 记录本来应该在的位置.如果输出的在判断的根和判断的值中间,则判断的入度--
int val;
}num[1001]; //下标作为hash的值
/*
这个函数不是得到真的输入 而是从散列后的结果输入
本来每个的值hash后应该等于下标,但是可能有冲突,故记录其根位置和入度
*/
int GetInput(int N)
{
int i,x,empty=0;
for(i=0;i<N;i++)
{
scanf("%d",&x);
//负数表示空
if(x<0)
{
num[i].in=-1;
num[i].root=-1;
empty++; //记录空值
}
else{
if(x%N==i)
{
num[i].in=0;
num[i].val=x;
num[i].root=x%N;
}
else{
num[i].val=x;
int temp=i-x%N;
if(temp<0)
temp+=N; //轮到第二圈了
num[i].in=temp; //与root的差距
num[i].root=x%N;
}
}
}
return empty;
}
void Output(int N,int empty)
{
int i,j,x,y,mini;
for(j=0;j<N-empty-1;j++)
{
int min=65536;
//每次找入度为0的最小的,题目要求
for(i=0;i<N;i++)
{
if(num[i].in==0&&num[i].val<min)
{
mini=i;
min=num[i].val;
}
}
printf("%d ",num[mini].val); //找最小的
num[mini].in=-1;
for(i=0;i<N;i++)
{
if(num[i].in>0)
if((i<num[i].root&&(mini<i||mini>=num[i].root))||(i>num[i].root&&mini<i&&mini>=num[i].root)) //输出的在根和所在位置中间,表明其原来占了位
num[i].in--;
}
}
//最后剩的一个
for(i=0;i<N;i++)
{
if(num[i].in==0)
printf("%d",num[i].val);
}
}
int main()
{
int N,i,x,empty;
scanf("%d",&N);
empty=GetInput(N);
Output(N,empty);
return 0;
}
528

被折叠的 条评论
为什么被折叠?



