POJ 3276-Face The Right Way (开关问题)

题目传送

枚举k,ff[i]记为区间[i,i+k-1]是否反转,从最左端开始逐一判断,若最左端向前,则不反转,区间向后移动,不再考虑最左端,sum表示i所处所有区间转向次数的和。

#include <iostream>
#include <cstring>
using namespace std;
const int maxn = 5005;

int n, ans_k, ans_m = 0x3f3f3f3f;
int an[maxn];
int ff[maxn];

int calc(int k)
{
	memset(ff, 0, sizeof(ff));
	int ret = 0, sum = 0;
	for (int i = 1; i + k - 1 <= n; i++) {
		if ((an[i] + sum) % 2) {
			ret++;
			ff[i] = 1;
		}
		sum += ff[i];
		if (i - k + 1 > 0) sum -= ff[i - k + 1];
	}
	for (int i = n - k + 2; i <= n; i++) {
		if ((an[i] + sum) % 2) return -1;
		if (i - k + 1 > 0) sum -= ff[i - k + 1];
	}
	return ret;
}

int main(void)
{
	cin >> n;
	for (int i = 1; i <= n; i++) {
		char ch;
		cin >> ch;
		if (ch == 'F') an[i] = 0;
		else an[i] = 1;
	}
	for (int k = 1; k <= n; k++) {
		int m = calc(k);
		if (m >= 0 && m < ans_m) {
			ans_m = m;
			ans_k = k;
		}
	}
	cout << ans_k << " " << ans_m;
	return 0;
}
发布了30 篇原创文章 · 获赞 50 · 访问量 5297

猜你喜欢

转载自blog.csdn.net/qq_43054573/article/details/104375470