#include<iostream>
#include<string>
using namespace std;
const int maxn = 5007;
bool D[maxn];
bool B[maxn];//B[i]表示第i个格子有没有翻转
int main()
{
int n;
ios::sync_with_stdio(false);
cin >> n;
string s;
for (int i = 0; i<n; i++)
{
cin >> s;
if (s[0] == 'B')
{
D[i] = 1;
}
else
{
D[i] = 0;
}
}
//方法穷举所有的k,统计每个k的最小翻转次数
int ans = n;
int ansk = -1;
for (int i = 1; i <= n; i++)
{
/*首先同一个开始位置翻转两次是没有意义的
有如下先检查最左边的,如果要反转,那必须进行,从这一个格子的连续k个的翻转
如果不必翻转那么必定不进行从这个格子开始的连续k个的翻转
以此向后推
*/
int cnt = 0;
int c = 0;//统计j前面连续不大于i的翻转次数情况
bool flag = true;
for (int j = 0; j<n; j++)
{
if (j + i <= n && (D[j] + c) % 2)//如果能翻转且要翻转,则翻转
{
B[j] = 1;
cnt++;
}
else
{
B[j] = 0;
}
if ((D[j] + c + B[j]) % 2)//检测当前格子是否翻转成正向了,因为后面的操作无法翻转这一个格子了
{
flag = false;
break;
}
c += B[j];//为下一位的检测跟新前面的翻转情况,类似于尺取法
if (j + 1 >= i)
{
c -= B[j + 1 - i];
}
}
if (flag&&ans>cnt)
{
ans = cnt;
ansk = i;
}
}
cout << ansk <<" "<< ans << endl;
return 0;
}
poj3276_翻转问题
最新推荐文章于 2021-08-08 18:33:09 发布