Codeforces Round #521 (Div. 3) D. Cutting Out

D. Cutting Out

题目链接https://codeforces.com/contest/1077/problem/D

题意:

给你n个数,现在要你选k个数出来,并且能够从这n个数种选取尽量多的这k个数。

 

题解:

一开始想的贪心+模拟,然后写崩了...

其实这个题二分一下选几组就好了,因为要选几个数是固定了的,所以我们可以用二分来判断可行性(根据二分的x和每个数出现的次数来判断),即是否可以选够k个数,这个很容易办到。

然后最后统计一下每个数出现的个数,最后无脑选输出答案就行了。

 

代码如下:

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N = 2e5+5;
int n,k;
int s[N],cnt[N];
vector <int> ans;
bool check(int x){
    ans.clear();
    for(int i=1;i<=N-5;i++){
        if(!cnt[i]) continue ;
        int need = min(cnt[i]/x,k-int(ans.size()));
        for(int j=1;j<=need;j++) ans.push_back(i);
        if(ans.size()==k) return true;
    }
    return false;
}
int main(){
    scanf("%d%d",&n,&k);
    for(int i=1;i<=n;i++){
        scanf("%d",&s[i]);
        cnt[s[i]]++;
    }
    int l=1,r=N,mid;
    int re;
    while(l<r){
        mid=l+r>>1;
        if(check(mid)){
            l=mid+1;
            re=mid;
        }else r=mid;
    }
    check(re);
    for(auto v:ans) printf("%d ",v);
    return 0;
}

 

posted @ 2019-01-20 12:01  heyuhhh  阅读(110)  评论(0编辑  收藏  举报