codeforces 1077D
Posted buerdepepeqi
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了codeforces 1077D相关的知识,希望对你有一定的参考价值。
题目:https://codeforces.com/contest/1077/problem/D
题意:给你一个长度为n的串,你需要在里面找到出现次数最多的长度为k的子序列(子序列中元素可重复),求这个子序列
题解:方法一:二分最大次数,然后将排序后的数依次填进去。
方法二:贪心,这个子序列出现的最大次数就是,将出现次数从大到小排序,从最大的开始找,找到第i个数可以使得第i个数的次数大于等于子序列出现的次数,并且前i个数出现次数的和除k大于最大出现的次数即可,最后子序列就直接一个个填数即可。
代码如下:
二分:
#include<cstdio> #include<cstring> #include<algorithm> #include<iostream> #include<vector> #include<set> #define LL long long #define debug(x) cout << "[" << x << "]" << endl using namespace std; const int mx = 2e5+10; struct node { int a, num; bool operator < (const node& b) const { return num > b.num; } }; vector<node> v; int a[mx], vis[mx]; int n, k; bool check(int mid) { int sum = 0; for (int i = 0; i < v.size(); i++) { sum += v[i].num/mid; } return sum >= k; } int main() { scanf("%d%d", &n, &k); for (int i = 1; i <= n; i++) { scanf("%d", &a[i]); vis[a[i]]++; } sort(a+1, a+1+n); int m = unique(a+1, a+n+1)-a-1; for (int i = 1; i <= m; i++) { v.push_back(node{a[i], vis[a[i]]}); } sort(v.begin(), v.end()); int l = 1, r = 1e9, ans = 0; while (l <= r) { int mid = (l+r)>>1; if (check(mid)) l = mid+1; else r = mid-1, ans = r; } for (int i = 0; i < v.size(); i++) { if (k == 0) break; int t = v[i].num/ans; while (t--) printf("%d ", v[i].a), k--; } return 0; }
贪心:
#include<bits/stdc++.h> using namespace std; const int maxn = 1e5+5; int vis[maxn*2]; struct node { int cnt; int id; } a[maxn]; bool cmp(node a,node b) { return a.cnt>b.cnt; } int main() { int n,k; int maxx=-1; scanf("%d%d",&n,&k); int x; for(int i=0; i<n; i++) { scanf("%d",&x); maxx=max(maxx,x); vis[x]++; } int t=0; for(int i=1; i<=maxx; i++) { if(vis[i]!=0) { a[t].cnt=vis[i]; a[t].id=i; t++; } } /***** 前面全部是去重和 *****/ sort(a,a+t,cmp); int sum=0,ans=0,id=0; for(int i=0;i<t;i++){ sum+=a[i].cnt; if(ans<=a[i].cnt&&sum/k>ans){//第i大的数出现的次数大于最多次数,更新最多次数 id=i;//记录最大到几 ans=sum/k;//会有多少个这样的t串 } } vector<int> vec; for(int i=0;i<=id;i++){ int time=a[i].cnt/ans;//这个数可以被放的次数 for(int j=0;j<time;j++){ vec.push_back(a[i].id); } } for(int i=0;i<vec.size();i++){ printf("%d ",vec[i]); } }
以上是关于codeforces 1077D的主要内容,如果未能解决你的问题,请参考以下文章
[Codeforces Round #522 (Div. 2, based on Technocup 2019 Elimination Round 3)][C. Playing Piano](代码片段
Codeforces 86C Genetic engineering(AC自动机+DP)
CodeForces 1005D Polycarp and Div 3(思维贪心dp)