codeforces Codeforces Round #521 (Div. 3) D. Cutting Out
阿新 • • 發佈:2018-12-22
題意:
傳送門
題意:
給出一個長度為n的字串,要求每次刪除k個字串,使剩下的字元最少的長度為k的字串。
思路:
求出最小的刪除次數和最大的刪除字數然後進行二分,然後求出最大的刪除次數。
為了操作方便,這裡進行了離散化。
程式碼如下:
#include <cstdio> #include <cstring> #include <algorithm> #include <iostream> #include <map> #include <vector> using namespace std; const int maxn=2*1e5+5; int n,k; struct node { int num; int id; }; node a[maxn]; int num=0; map<int,int>ma; vector<int>v; int judge (int x) { int sum=0; for (int i=1;i<=num;i++) { if(a[i].num<x) continue; sum+=a[i].num/x; } if(sum>=k) return 1; return 0; } int main() { memset (a,0,sizeof(a)); scanf("%d%d",&n,&k); for (int i=0;i<n;i++) { int x; scanf("%d",&x); if(ma[x]==0) { ma[x]=++num; a[num].id=x; } a[ma[x]].num++; } int l=1,r=n,ans=1; while (l<=r) { int mid=(l+r)>>1; if(judge(mid)) { ans=mid; l=mid+1; } else { r=mid-1; } } for (int i=1;i<=num;i++) { if(a[i].num<ans) continue; for (int j=0;j<a[i].num/ans;j++) { if(v.size()<k) v.push_back(a[i].id); else break; } if(v.size()>=k) break; } for (int i=0;i<k;i++) printf("%d%c",v[i],i==k-1?'\n':' '); return 0; }