Codeforces Round #715 (Div. 2) D. Binary Literature

链接

https://codeforces.com/contest/1509/problem/d

题意

三个长度为 $2n$ 的 $01$ 字符串 $a,b,c$,构造一个长度不超过 $3n$ 的 $01$ 字符串 $T$ 至少 $a,b,c$ 中两个是 $T$ 的子序列。

思路

建立三个指针分别对 $a,b,c$ 从左向右扫描。

每次至少有两个字符相同,输出当前字符,将两个指针向右移动,直到一个字符串被扫描完。

设当前已经输出 $k$ 个字符,总共移动 $2k$ 次,有一个字符串被扫描完,移动 $2n$ 次,那么剩下两个字符串移动 $2k-2n$ 次,平均 $k-n$ 次,最多剩下 $2n-(k-n)$ 个字符未添加,选最优的输出剩余部分。

总共最多 $2n+(2n-(k-n))=5n-k$ 个字符,因为 $k>=2n$ 所以肯定不超过 $3n$。

代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
#include <bits/stdc++.h>
#define SZ(x) (int)(x).size()
#define ALL(x) (x).begin(),(x).end()
#define PB push_back
#define EB emplace_back
#define MP make_pair
#define FI first
#define SE second
using namespace std;
typedef double DB;
typedef long double LD;
typedef long long LL;
typedef unsigned long long ULL;
typedef pair<int,int> PII;
typedef vector<int> VI;
typedef vector<PII> VPII;
// head
int main() {
ios::sync_with_stdio(false);
cin.tie(nullptr);
int T;cin>>T;
while(T--) {
int n;cin>>n;
string a,b,c;cin>>a>>b>>c;
int aa=0,bb=0,cc=0;
while(aa<2*n&&bb<2*n&&cc<2*n) {
if(a[aa]==b[bb]) cout<<a[aa],++aa,++bb;
else if(a[aa]==c[cc]) cout<<a[aa],++aa,++cc;
else if(b[bb]==c[cc]) cout<<b[bb],++bb,++cc;
}
if(aa==2*n) cout<<(bb>cc?b.substr(bb,2*n-bb):c.substr(cc,2*n-cc))<<'\n';
else if(bb==2*n) cout<<(aa>cc?a.substr(aa,2*n-aa):c.substr(cc,2*n-cc))<<'\n';
else if(cc==2*n) cout<<(aa>bb?a.substr(aa,2*n-aa):b.substr(bb,2*n-bb))<<'\n';
}
return 0;
}