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; }