这道题,其实是很水的二分题,关键是要想到二分什么比较合适。

这道题要最大化数组中每个数出现的次数,而且每个数出现的次数知道后,数组中可以出现多少个合法的值也就知道了。

注意二分之后得出的最大出现次数之后,从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");
}