场上过了大样例没管了,但是看到讨论区一个很像的思路寄了,重写了发现我好像没被 hack。
做法是维护当前 a,b 两个串 0/1 的个数,从左到右扫,如果当前 ci=1,那么找到这个 1 能延伸多远,把经过的字符全部加到 a 当前的 0/1 个数里面,对于 d 同理。如果 ci=0 的话就只加入当前一个字符。然后如果当前 a,b 都有 0,就把 0 消了,答案加 1,否则如果都有 1,把 1 消了,答案加 1,否则答案不加。然后如果 ci=0 或者 ci+1=0,那么把 a 当前的 0 和 1 个数都清空。
说的不是很清楚,给个代码(a0,a1 就是 a 中 0/1 的数量)。
#include <cstdio>
char a[1000005], b[1000005], c[1000005], d[1000005];
int n, ans;
int main() {
scanf("%d%s%s%s%s", &n, a + 1, b + 1, c + 1, d + 1);
int a0 = 0, a1 = 0, b0 = 0, b1 = 0;
for (int i = 1; i <= n; ++ i) {
if (c[i] == '0') {if (a[i] == '0') ++ a0; else ++ a1;}
else if (i == 1 || c[i - 1] == '0') {
if (a[i] == '0') ++ a0; else ++ a1;
int j = i;
while (j < n && c[j + 1] == '1') {
++ j;
if (a[j] == '0') ++ a0; else ++ a1;
}
}
if (d[i] == '0') {if (b[i] == '0') ++ b0; else ++ b1;}
else if (i == 1 || d[i - 1] == '0') {
if (b[i] == '0') ++ b0; else ++ b1;
int j = i;
while (j < n && d[j + 1] == '1') {
++ j;
if (b[j] == '0') ++ b0; else ++ b1;
}
}
if (a0 && b0) -- a0, -- b0, ++ ans;
else if (a1 && b1) -- a1, -- b1, ++ ans;
if (i == n || c[i] == '0' || c[i + 1] == '0') a0 = a1 = 0;
if (i == n || d[i] == '0' || d[i + 1] == '0') b0 = b1 = 0;
}
printf("%d", ans);
return 0;
}