题解 [ARC132D] Between Two Binary Strings
题意
参见题意翻译。
分析
对于在 \(s_1\) 和 \(s_2\) 之间的字符串 \(s_3\),那么 \(s_3\) 的第 \(i\) 个 \(1\) 的位置一定在 \(s_1\) 和 \(s_2\) 的第 \(i\) 个 \(1\) 的位置之间。
为了使答案最大,就要尽量让相同的数字挨在一起。
很容易证明每一个 \(1\) 的可选区间一定不会存在包含关系,所以依次考虑每一个区间,将 \(1\) 放在区间尽量靠后的位置。
有一种特殊的情况:
111100
011110
根据刚刚的贪心策略得到的答案 011110 是不优的,因为将两个 \(0\) 分开了,所以我们再尝试一种情况,将第一个区间放在最靠前的位置。
两种情况答案取最大值即可,时间复杂度 \(O(n+m)\)。
代码
//the code is from chenjh
#include<cstdio>
#include<cstring>
#include<algorithm>
#define MAXN 300003
using namespace std;
int n,m,e;
char s[MAXN],t[MAXN];
struct SEG{
int l,r;
bool operator < (const SEG&B)const{return l<B.l;}
}a[MAXN];
bool p[MAXN];
int f(const bool op){
memset(p+1,0,e);
int w=0,ret=0;
for(int i=1;i<=m;i++,++w) p[w=a[i].l>w?op&&i==1?a[i].l:a[i].r:w]=1;//位置不在当前区间内,就重新选择放在右端点。
for(int i=2;i<=e;i++) ret+=p[i]==p[i-1];//统计答案。
return ret;
}
int main(){
scanf("%d%d %s %s",&n,&m,s+1,t+1),e=n+m;
int t1=0,t2=0;
for(int i=1;i<=e;i++){
if(s[i]=='1') a[++t1].l=i;//统计 1 出现的位置。
if(t[i]=='1') a[++t2].r=i;
}
for(int i=1;i<=m;i++)if(a[i].l>a[i].r) swap(a[i].l,a[i].r);
printf("%d\n",max(f(0),f(1)));//求两种答案最大值。
return 0;
}

浙公网安备 33010602011771号