D. Cutting Out
Posted mch5201314
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了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<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;
}
以上是关于D. Cutting Out的主要内容,如果未能解决你的问题,请参考以下文章
Codeforces Round #521 (Div. 3) D. Cutting Out 二分+排序
Codeforces Round #521 (Div. 3) D. Cutting Out
codeforces 1077D Cutting Out 二分
AtCoder AISing Programming Contest 2019 Task D. Nearest Card Game