NOIP T1求hack/正确性证明
  • 板块学术版
  • 楼主Stinger
  • 当前回复0
  • 已保存回复0
  • 发布时间2024/11/30 14:27
  • 上次更新2024/11/30 15:58:55
查看原帖
NOIP T1求hack/正确性证明
361308
Stinger楼主2024/11/30 14:27

场上过了大样例没管了,但是看到讨论区一个很像的思路寄了,重写了发现我好像没被 hack。

做法是维护当前 a,ba,b 两个串 0/1 的个数,从左到右扫,如果当前 ci=1c_i=1,那么找到这个 1 能延伸多远,把经过的字符全部加到 aa 当前的 0/1 个数里面,对于 dd 同理。如果 ci=0c_i=0 的话就只加入当前一个字符。然后如果当前 a,ba,b 都有 0,就把 0 消了,答案加 11,否则如果都有 1,把 1 消了,答案加 11,否则答案不加。然后如果 ci=0c_i=0 或者 ci+1=0c_{i+1}=0,那么把 aa 当前的 0011 个数都清空。

说的不是很清楚,给个代码(a0,a1 就是 aa 中 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; 
}
2024/11/30 14:27
加载中...