D. Cutting Out
阿新 • • 發佈:2018-12-04
---恢復內容開始---
連結
[https://codeforces.com/contest/1077/problem/D]
題意
給你n,k,n個數,找出長度為k,的子串(不需連續),使得該子串數量最多
分析
1.肯定統計每個數字的數量
2.看那些數字數量大於0,儲存數量和該數數值
3.對儲存的根據數量從小到大排序
4.reverse就變成從大到小排序
5.選出前數量前k大的前k個數,
6.二分貪心查詢
很經典的二分吧
程式碼
#include<bits/stdc++.h> using namespace std; #define pb push_back #define mp make_pair #define fi first #define se second const int N=2e5+10; int f[N]; int main(){ ios::sync_with_stdio(false); cin.tie(0); cout.tie(0); int n,k,x,i,j,ma; ma=0; //freopen("in.txt","r",stdin); cin>>n>>k; for(i=0;i<n;i++){ cin>>x; f[x]++; ma=max(ma,x); } vector<pair<int,int> > v1,v2; for(i=1;i<=ma;i++) if(f[i]) v1.pb(mp(f[i],i)); sort(v1.begin(),v1.end()); reverse(v1.begin(),v1.end()); j=0; for(i=0;i<v1.size();i++) { j++; if(j>k) break; v2.pb(mp(v1[i].fi,v1[i].se)); } vector<int> ans; int l=1,r=N; while(l<=r){ int mid=(l+r)>>1; int sum=0; vector<int> tem; for(i=0;i<v2.size();i++) tem.pb(v2[i].fi/mid),sum+=tem[i]; if(sum>=k){ ans.clear(); int cnt=0; for(i=0;i<v2.size();i++){ int t=tem[i]; while(cnt<k&&t--) ans.pb(v2[i].se),cnt++; } l=mid+1; } else r=mid-1; } for(i=0;i<ans.size();i++) cout<<ans[i]<<' '; cout<<endl; return 0; }