CF1689A题解
题意简述
给定字符串 \(a\) 和 \(b\),每次从 \(a\) 串或 \(b\) 串中选出一个字符加入 \(c\) 串,要求 \(c\) 串的字典序最小。特别地,在 \(c\) 串中不能出现连续 \(k\) 次来源相同的字符。
思维路径
由于字符是随意选取的,易于发现每次选 \(a\) 串中字典序最小的字符或者 \(b\) 串中字典序最小的字符一定比其他方案更优,因此先对 \(a\) 串和 \(b\) 串按照字典序排序。
接下来考虑新加入 \(c\) 串的字符,假设对于两个串来说分别是加入 \(a_i\) 和 \(b_j\),有如下两种情况。
- 若无论加入哪个串都不会出现连续 \(k\) 个来源相同的字符,那么选 \(a_i\) 和 \(b_j\) 字典序更小的那一个。
- 若加入某个串的字符会出现连续 \(k\) 个来源相同的字符,那么选另一个串的字符。
最终某一个串被选完的时候立刻结束,此时的 \(c\) 串就是答案。
AC 代码
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const ll N=109;
ll T,n,m,k;
char a[N],b[N],c[N*2];
ll nw,num,cnt;
void input(){
cin>>n>>m>>k;
for(ll i=1;i<=n;i++) cin>>a[i];
for(ll j=1;j<=m;j++) cin>>b[j];
}
void solve(){
sort(a+1,a+n+1);
sort(b+1,b+m+1);
cnt=0;
ll j=1;
nw=0; num=0;
for(ll i=1;i<=n;i++){
while(num==k||(j<=m&&a[i]>b[j])){
c[++cnt]=b[j];
j++;
if(nw==2){
num++;
}
else{
nw=2; num=1;
}
if(num==k) break;
}
if(j>m) break;
c[++cnt]=a[i];
if(nw==1){
num++;
}
else{
nw=1; num=1;
}
}
for(ll i=1;i<=cnt;i++) cout<<c[i]; cout<<"\n";
}
int main(){
cin>>T;
while(T--){
input();
solve();
}
return 0;
}
本文来自博客园,作者:lemon-cyy,转载请注明原文链接:https://www.cnblogs.com/lemon-cyy/p/17984635