题意:给定n个数,使得n个数都在1~m范围内,并且每个数的个数都等于或接近 n/m 个!
思路:1.将缺少的数都依次存放在一个数组里
2.遍历n个数,将不符合条件的换掉即可。
不符合条件:(1)大于m的数;(2)符合范围但个数大于n/m个数的元素。
代码:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define INIT(x) memset(x,0,sizeof(x))
int main()
{
int i,n,m,a[2005],flag[2005];
while(scanf("%d%d",&n,&m)!=EOF)
{
INIT(flag);//初始化,用于累计每个元素出现的个数
for(i=0;i<n;i++)
{
scanf("%d",&a[i]);
if(a[i] <= m)//将小于m的数计数
flag[a[i]]++;
}
int temp[2005],index = 0;
for(i=1;i<=m;i++)//将缺少的数放入一个数组
{
while(flag[i] < n/m)
{
temp[index++] = i;
flag[i]++;
}
}
int top = 0;
for(i=0;i<n;i++)
{
if(top == index)//当所有缺少的元素全部放完跳出即可
break;
if(a[i] > m)//将缺少的元素放到大于m的位置上
a[i] = temp[top++];
if(flag[a[i]] > n/m)//将缺少的元素放到符合元素的多余的位置上
{
flag[a[i]]--;
a[i] = temp[top++];
}
}
printf("%d %d\n",n/m,index);
for(i=0;i<n;i++)
printf("%d ",a[i]);
printf("\n");
}
return 0;
}