贪心求 hack
查看原帖
贪心求 hack
36580
L_RUA楼主2024/12/2 13:35

大致思路就是从前往后考虑每个不能交换的点,每次更靠后的不能交换的点尽量去满足前面的,并且维护好剩余的数量

目前大样例得到的结果偏大。。。想不明白为什么

#include <bits/stdc++.h>

using namespace std;

inline int read(){
	int x = 0, f = 1;
	char ch = getchar();
	//一直没有读到数字,注意处理负号 
	while (ch < '0' || ch > '9') {
		if(ch == '-') {
			f = -1;	
		}
		ch = getchar();
	}
	//一位位读进数字 
	while (ch >= '0' && ch <= '9') {
		//等价于 x * 10 + ch - '0' 
		x = (x << 3) + (x << 1) + ch - '0';
		ch = getchar();
	}
	//符号乘上数字 
	return x * f;
}

const int maxn = 100005;

int n;
char s1[maxn];
char s2[maxn];
char t1[maxn];
char t2[maxn];

//统计两个序列可用的 0/1 数量 
int cnt1[2];
int cnt2[2];

void clr() {
	cnt1[0] = cnt1[1] = 0;
	cnt2[0] = cnt2[1] = 0;
}

void solve() {
	int ans = 0;
	int p1 = 0, p2 = 0;
	while (p1 <= n && p2 <= n) {
		while (p1 + 1 <= n && t1[p1 + 1] != '0') {
			++p1;
			++cnt1[s1[p1] - '0'];
		}
		while (p2 + 1 <= n && t2[p2 + 1] != '0') {
			++p2;
			++cnt2[s2[p2] - '0'];
		}
		//比较 p1, p2 来贪心
//		printf("test1: %d %d %d\n", p1, p2, ans);
//		printf("test2: %d %d %d %d\n", cnt1[0], cnt1[1], cnt2[0], cnt2[1]);
		ans += min(cnt1[0], cnt2[0]) + min(cnt1[1], cnt2[1]);
		//两者相等,直接贪心匹配所有 
		
		if (p1 == p2) {
			//全部清 0 即可 
			cnt1[0] = cnt2[0] = 0;
			cnt1[1] = cnt2[1] = 0;
			if (p1 + 1 <= n && p2 + 1 <= n && s1[p1 + 1] == s2[p2 + 1]) { //两个固定动不了的 
				++ans;
			}
			++p1; ++p2; 
		} else if (p1 > p2) { // p1 > p2 
			//先减去一定能匹配的
			cnt1[0] = max(0, cnt1[0] - cnt2[0]);
			cnt1[1] = max(0, cnt1[1] - cnt2[1]);
			if (p2 + 1 <= n && cnt1[s2[p2 + 1] - '0']) { //特判末尾 
				++ans; 
				--cnt1[s2[p2 + 1] - '0'];
			}
			//往后占空位 
			cnt1[0] = min(cnt1[0], p1 - p2);
			cnt1[1] = min(cnt1[1], p1 - p2);
			cnt2[0] = cnt2[1] = 0;
			++p2;
		} else { // p2 > p1
			cnt2[0] = max(0, cnt2[0] - cnt1[0]);
			cnt2[1] = max(0, cnt2[1] - cnt1[1]);
			if (p1 + 1 <= n && cnt2[s1[p1 + 1] - '0']) { //特判末尾 
				++ans;
				--cnt2[s1[p1 + 1] - '0'];
//				puts("here");
			}
			cnt2[0] = min(cnt2[0], p2 - p1);
			cnt2[1] = min(cnt2[1], p2 - p1);
			cnt1[0] = cnt1[1] = 0;
			++p1;
		}
//		printf("test3: %d %d %d %d %d\n", cnt1[0], cnt1[1], cnt2[0], cnt2[1], ans);
	}
	printf("%d\n", ans);
}

int main() {
//	freopen("./edit/edit2.in", "r", stdin);
	int T;
	scanf("%d", &T);
	while(T--) {
		clr();
		scanf("%d", &n);
		scanf("%s%s%s%s", s1 + 1, s2 + 1, t1 + 1, t2 + 1);
		solve();
	} 
	
	return 0;
} 
2024/12/2 13:35
加载中...