CF1077D Cutting Out(二分)

题意:

给出一串序列,请你找出一个大小为k的元素集合,使得可以在这个序列中找到数量最大的集合拷贝。

题解:

一开始想到背包去了,其实不用这么麻烦,以拷贝数为条件做一个二分查找,时间复杂度nlogn。

#include<bits/stdc++.h>
 
using namespace std;
const int maxn=2e5+100;
int n,k;
int a[maxn];
int pos[maxn];
 
 
int main () {
    cin>>n>>k;
    for (int i=1;i<=n;i++) scanf("%d",&a[i]);
    for (int i=1;i<=n;i++) pos[a[i]]++;
 
    int l=1,r=2e5+10;
    int ans=0;
    while (l<=r) {
        int mid=(l+r)>>1;
        int sum=0;
        for (int i=1;i<=2e5;i++) sum+=pos[i]/mid;
        if (sum>=k)
            l=mid+1,ans=mid;
        else
            r=mid-1;
    }
    //printf("%d\n",ans);
    int tot=0;
    for (int i=1;i<=2e5+10;i++) {
        for (int j=1;j<=pos[i]/ans&&++tot<=k;j++)
            printf("%d ",i);
    }
 
}

 

posted @ 2020-05-21 13:16  zlc0405  阅读(182)  评论(0编辑  收藏  举报