这道题,其实是很水的二分题,关键是要想到二分什么比较合适。
这道题要最大化数组中每个数出现的次数,而且每个数出现的次数知道后,数组中可以出现多少个合法的值也就知道了。
注意二分之后得出的最大出现次数之后,从cnt数组中取出合法值,取出第k个值后return 0;
#include<bits/stdc++.h>
using namespace std;
int a[200010];
int cnt[200010];
int b[200010];
int tot;
int k;
bool check(int mid)
{
int kk=0;
for(int i=1;i<=tot;i++)
{
int num=cnt[b[i]]/mid;
kk+=num;
}
return kk>=k;
}
int main()
{
int n;
scanf("%d%d",&n,&k);
for(int i=1;i<=n;i++)
{
scanf("%d",&a[i]);
cnt[a[i]]++;
}
for(int i=1;i<=200000;i++)
{
if(cnt[i])
b[++tot]=i;
}
int l=1,r=200000;
int best=0;
while(l<=r)
{
int mid=(l+r)/2;
if(check(mid))
{
l=mid+1;
best=mid;
}
else
{
r=mid-1;
}
}
int cntk=0;
for(int i=1;i<=tot;i++)
{
int num=cnt[b[i]]/best;
if(num)
{
for(int j=1;j<=num;j++)
{
printf("%d ",b[i]);
cntk++;
if(cntk==k)
{
printf("\n");
return 0;
}
}
}
}
printf("\n");
}