Polycarp is a music editor at the radio station. He received a playlist for tomorrow, that can be represented as a sequence a1, a2, ..., an, where ai is a band, which performs the i-th song. Polycarp likes bands with the numbers from 1 to m, but he doesn't really like others.
We define as bj the number of songs the group j is going to perform tomorrow. Polycarp wants to change the playlist in such a way that the minimum among the numbers b1, b2, ..., bm will be as large as possible.
Find this maximum possible value of the minimum among the bj (1 ≤ j ≤ m), and the minimum number of changes in the playlist Polycarp needs to make to achieve it. One change in the playlist is a replacement of the performer of the i-th song with any other group.
The first line of the input contains two integers n and m (1 ≤ m ≤ n ≤ 2000).
The second line contains n integers a1, a2, ..., an (1 ≤ ai ≤ 109), where ai is the performer of the i-th song.
In the first line print two integers: the maximum possible value of the minimum among the bj (1 ≤ j ≤ m), where bj is the number of songs in the changed playlist performed by the j-th band, and the minimum number of changes in the playlist Polycarp needs to make.
In the second line print the changed playlist.
If there are multiple answers, print any of them.
4 2 1 2 3 2
2 1 1 2 1 2
7 3 1 3 2 2 2 2 1
2 1 1 3 3 2 2 2 1
4 4 1000000000 100 7 1000000000
1 4 1 2 3 4
In the first sample, after Polycarp's changes the first band performs two songs (b1 = 2), and the second band also performs two songs (b2 = 2). Thus, the minimum of these values equals to 2. It is impossible to achieve a higher minimum value by any changes in the playlist.
In the second sample, after Polycarp's changes the first band performs two songs (b1 = 2), the second band performs three songs (b2 = 3), and the third band also performs two songs (b3 = 2). Thus, the best minimum value is 2.
题意
有一个歌单,歌单上面有n首歌,你喜欢1,2,3....m号乐队唱的歌。
你希望改变这个歌单,使得你喜欢的乐队们唱歌唱得最少的尽量大。
问你最少修改多少次,且输出方案。
注意并非歌单上所有的歌都需要修改成1-m乐队唱的,只要满足使得你喜欢的乐队们唱歌唱得最少的尽量大即可。
题解:
显然最终你喜欢的乐队们唱歌数目为n/m。
首先计算当前不在1-m区间的乐队数目f,并计算出需要从f个乐队中修改的个数ff=(n/m)*m-(n-f),注意若ff<0时说明不需要从不在1-m区间的乐队转化,那么此时ff=0。
对于不在1-m区间的需要转化乐队,首先转化为1-m区间中个数少的,对所以的执行完毕后,再对1-m的乐队“均衡”分配,贪心得转化,实现详见代码:
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<vector>
#include<queue>
using namespace std;
const int MAXN=2000+100;
struct node
{
int id,num;
}b[MAXN];
struct cmp1
{
bool operator()(node a,node b)
{
return a.num>b.num;
}
};
bool cmp2(node a,node b)
{
return a.num<b.num;
}
int a[MAXN];
vector<int> re;
int main()
{
int n,m;
scanf("%d%d",&n,&m);
for(int i=1;i<=m;i++) b[i].id=i;
int f=0;
for(int i=1;i<=n;i++)
{
scanf("%d",&a[i]);
if(1<=a[i]&&a[i]<=m) b[a[i]].num++;
else re.push_back(i),f++; //f表示不在1-m中元素个数
}
int ff=(n/m)*m-(n-f); //ff表示f中需要修改的元素个数
if(ff<0) ff=0; //注意这一点,当时少了这个条件就没过
while(f>ff)
{
re.erase(re.begin());f--;
}
priority_queue<node,vector<node>,cmp1> q;
for(int i=1;i<=m;i++) q.push(b[i]);
int ans=0;
for(int i=0;i<re.size();i++) //对需要修改的进行修改,替换成1-m中个数最少的
{
int p=re[i];
node top=q.top();
q.pop();
a[p]=top.id;
top.num++;
b[top.id].num++;
q.push(top);
ans++;
}
for(int i=1;i<=m;i++) //个数少于n/m的数需要增加,最少需要增加n/m-b[i].num
{
if(b[i].num<n/m) ans+=n/m-b[i].num;
}
vector<int> ch;
for(int i=1;i<=n;i++)
{
if(a[i]>m) continue;
if(b[a[i]].num>n/m)
ch.push_back(i),b[a[i]].num--; //ch中储存1-m中个数大于n/m的数可以改变的位置
}
for(int i=1;i<=m;i++)
{
while(b[i].num<n/m)
{
a[ch[0]]=i;
b[i].num++;
ch.erase(ch.begin());
}
}
printf("%d %d\n",n/m,ans);
for(int i=1;i<=n;i++)
printf("%d%c",a[i],i==n?'\n':' ');
return 0;
}