求巨型代码hack
查看原帖
求巨型代码hack
481337
Pratty楼主2024/12/4 21:27

不用管这个代码的作用,求 hack 即可。 数据不要太大, n 最好在 10 以内,最好满足 B 性质。

hack 成立悬关

#include <bits/stdc++.h>
using namespace std; 
const int N = 110000;
int t, n, ans, tot;
//h1,h2记录当前是可交换/不可交换
//a10,a11,a20,a21记录第1/2条字符串当前这一组的0/1个数
//sum11,sum10,sum21,sum20记录当前字符串的大组的1/0的个数
//id1,id2记录当前小组下标所指向的大组的小标的值
int h1[N], h2[N], a11[N], a10[N], a21[N], a20[N], sum10[N], sum20[N], sum11[N], sum21[N], cnt1, cnt2, id1[N], id2[N];
char s1[N], s2[N];
char t1[N], t2[N];
int main() {
//	freopen("v.txt", "r", stdin);
//	freopen("ans.txt", "w", stdout);
	scanf("%d", &t);
	while (t--) {
		ans = 0;
		tot = 0;
		cnt1 = 0, cnt2 = 0;
		scanf("%d", &n);
		scanf("%s\n%s", s1 + 1, s2 + 1);
		scanf("%s\n%s", t1 + 1, t2 + 1);
		for (int i = 1; i <= n; i++) {
			if (t1[i] == '1' && t1[i - 1] != '1' && t1[i + 1] != '1') t1[i] = '0';
			if (t2[i] == '1' && t2[i - 1] != '1' && t2[i + 1] != '1') t2[i] = '0';
		}
		int lst = 1, yi1 = s1[1] - '0', yi2 = s2[1] - '0';
		for (int i = 2; i <= n; i++) {
			if (t1[i] != t1[i - 1] || t2[i] != t2[i - 1]) {
				if (t1[i - 1] == '1') {
					h1[++tot] = 1;
				} else h1[++tot] = 0;
				if (t2[i - 1] == '1') {
					h2[tot] = 1;
				} else h2[tot] = 0;
				a11[tot] = yi1, a10[tot] = i - lst - yi1;
				a21[tot] = yi2, a20[tot] = i - lst - yi2;
				yi1 = s1[i] - '0', yi2 = s2[i] - '0';
				lst = i;
			} else {
				yi1 += s1[i] - '0', yi2 += s2[i] - '0';
			}
		}
		if (t1[n] == '1') h1[++tot] = 1;
		else h1[++tot] = 0;
		if (t2[n] == '1') h2[tot] = 1;
		else h2[tot] = 0;
		a11[tot] = yi1, a10[tot] = n - lst + 1 - yi1;
		a21[tot] = yi2, a20[tot] = n - lst + 1 - yi2;
		int one1 = 0, one2 = 0;
		int zer1 = 0, zer2 = 0;
		for (int i = 1; i <= tot + 1; i++) {
			if (i > 1 && h1[i - 1] == 1 && h1[i] == 0) {
				cnt1++;
				sum11[cnt1] = one1;
				sum10[cnt1] = zer1;
				one1 = 0;
				zer1 = 0;
			} else if (h1[i] == 1) {
				one1 += a11[i];
				zer1 += a10[i];
				id1[i] = cnt1 + 1;
			}
			if (i > 1 && h2[i - 1] == 1 && h2[i] == 0) {
				cnt2++;
				sum21[cnt2] = one2;
				sum20[cnt2] = zer2;
				one2 = 0;
				zer2 = 0;
			} else if (h2[i] == 1) {
				one2 += a21[i];
				zer2 += a20[i];
				id2[i] = cnt2 + 1;
			}
		}
//		cout << sum21[1] << endl;
		for (int i = 1; i <= tot; i++) {
			if (h1[i] == 0 && h2[i] == 0) continue;//上下都不可交换单独处理 
			if (h1[i] == 1 && h2[i] == 1) {//上下均可交换 
//				if (i == 5) cout << ans << endl;
				if (h1[i + 1] == 0 && h2[i + 1] == 0) {//上下的下一个都不可交换 
					ans += min(sum11[id1[i]], sum21[id2[i]]) + min(sum10[id1[i]], sum20[id2[i]]);
				} else if (h1[i + 1] == 1 && h2[i + 1] == 0) {//上的下一个可交换 
					ans += min(sum11[id1[i]], sum21[id2[i]]) + min(sum10[id1[i]], sum20[id2[i]]);
					int t1 = min(sum11[id1[i]], sum21[id2[i]]);
					int t2 = min(sum10[id1[i]], sum20[id2[i]]);
					if (min(sum11[id1[i]], sum21[id2[i]]) + min(sum10[id1[i]], sum20[id2[i]]) != a11[i] + a10[i]) {
						if (sum11[id1[i]] - t1) sum11[id1[i]] -= a11[i] + a10[i] - (min(sum11[id1[i]], sum21[id2[i]]) + min(sum10[id1[i]], sum20[id2[i]]));
						else sum10[id1[i]] -= a11[i] + a10[i] - (min(sum11[id1[i]], sum21[id2[i]]) + min(sum10[id1[i]], sum20[id2[i]]));
					}
					sum11[id1[i]] -= t1;
					sum10[id1[i]] -= t2;
				} else if (h1[i + 1] == 0 && h2[i + 1] == 1) {//下的下一个可交换 
//					if (i == 5) cout << min(sum10[id1[i]], sum20[id2[i]]) << endl;
//					if (i == 5) cout << ans << endl;
					ans += min(sum11[id1[i]], sum21[id2[i]]) + min(sum10[id1[i]], sum20[id2[i]]);
					int t1 = min(sum11[id1[i]], sum21[id2[i]]);
					int t2 = min(sum10[id1[i]], sum20[id2[i]]); 
					if (min(sum11[id1[i]], sum21[id2[i]]) + min(sum10[id1[i]], sum20[id2[i]]) != a11[i] + a10[i]) {
						if (sum21[id2[i]] - t1) sum21[id2[i]] -= a11[i] + a10[i] - (min(sum11[id1[i]], sum21[id2[i]]) + min(sum10[id1[i]], sum20[id2[i]]));
						else sum20[id2[i]] -= a11[i] + a10[i] - (min(sum11[id1[i]], sum21[id2[i]]) + min(sum10[id1[i]], sum20[id2[i]]));
					}
					sum21[id2[i]] -= t1;
					sum20[id2[i]] -= t2;
				}
//				if (i == 4) cout << ans << endl;
			} else if (h1[i] == 1 && h2[i] == 0) {//上可以交换 
				ans += min(sum11[id1[i]], a21[i]) + min(sum10[id1[i]], a20[i]);
				int t1 = min(sum11[id1[i]], a21[i]);
				int t2 = min(sum10[id1[i]], a20[i]);
				if (min(sum11[id1[i]], a21[i]) + min(sum10[id1[i]], a20[i]) != a11[i] + a10[i]) {
					if (sum11[id1[i]] - t1) sum11[id1[i]] -= a11[i] + a10[i] - (min(sum11[id1[i]], a21[i]) + min(sum10[id1[i]], a20[i]));
					else sum10[id1[i]] -= a11[i] + a10[i] - (min(sum11[id1[i]], a21[i]) + min(sum10[id1[i]], a20[i]));
//					if (sum11[id1[i]] - t1) cout << i << endl;
//					if (i == 4) cout << a11[i] + a10[i] << endl;
				}
				sum11[id1[i]] -= t1;
				sum10[id1[i]] -= t2;
//				if (i == 1) cout << ans << endl;
			} else if (h1[i] == 0 && h2[i] == 1) {//下可以交换 
//				if (i == 5) cout << sum21[1] << endl;
				ans += min(a11[i], sum21[id2[i]]) + min(a10[i], sum20[id2[i]]);
				int t1 = min(a11[i], sum21[id2[i]]);
				int t2 = min(a10[i], sum20[id2[i]]);
				if (min(a11[i], sum21[id2[i]]) + min(a10[i], sum20[id2[i]]) != a11[i] + a10[i]) {
					if (sum21[id2[i]] - t1) sum21[id2[i]] -= a11[i] + a10[i] - (min(a11[i], sum21[id2[i]]) + min(a10[i], sum20[id2[i]]));
					else sum20[id2[i]] -= a11[i] + a10[i] - (min(a11[i], sum21[id2[i]]) + min(a10[i], sum20[id2[i]]));
				}
				sum21[id2[i]] -= t1;
				sum20[id2[i]] -= t2;
			}
		}
//		cout << ans << endl;
		for (int i = 1; i <= n; i++) {
			if (t1[i] == '0' && t2[i] == '0') {
				if (s1[i] == s2[i]) {
					ans++;
				}
			}
		}
		printf("%d\n", ans);
	}
	return 0;
}
/*
1
11
01000100110
11011100110
11110111110
00111110000
1
8
11000111
11111000
11111000
00011111
1
16
0110010110110111
1001100110011001
1111100111111110
0001111100111100
ANS=14;
1
20
01000100111101100010
10111011000010011101
00011111001110011100
01111001111111100111
ANS=10;
1
9
101111111
100111000
110111011
011111111
//101111111
//101110000
ANS=5;
*/
2024/12/4 21:27
加载中...