D. Cutting Out

---恢复内容开始---

###链接 [https://codeforces.com/contest/1077/problem/D] ###题意 给你n,k,n个数,找出长度为k,的子串(不需连续),使得该子串数量最多 ###分析 1.肯定统计每个数字的数量 2.看那些数字数量大于0,保存数量和该数数值 3.对保存的根据数量从小到大排序 4.reverse就变成从大到小排序 5.选出前数量前k大的前k个数, 6.二分贪心查找 很经典的二分吧 ###代码 ``` #include 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>x; f[x]++; ma=max(ma,x); } vector > 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;ik) 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;

}

posted @ 2018-12-04 23:17  ChunhaoMo  阅读(197)  评论(0编辑  收藏  举报