反转 革命尚未成功,同志仍需努力
传送门
将K枚举,判断每次需要反转的次数,有点巧妙,用o(n)解决问题.
#include <cstdio>
#include <map>
#include <set>
#include <iostream>
using namespace std;
const int maxn = 5e3+100;
int a[maxn] , n , f[maxn];
int calc(int k)
{
memset(f,0,sizeof(f));
int res = 0, sum = 0;
for(int i=0;i+k<=n;i++)
{
if((a[i]+sum)%2!=0)
{
res++;
f[i] = 1;
}
sum += f[i];
if(i-k+1>=0){sum-=f[i-k+1];}
}
for(int i = n-k+1;i<=n;i++)
{
if((a[i]+sum)%2!=0){return -1;}
if(i-k+1>=0){sum-=f[i-k+1];}
}
return res;
}
int main()
{
map<char,int>mp;
mp['B'] = 1,mp['F'] = 0;
cin >> n;
char ch;
for(int i=0;i<n;i++)
{
cin >> ch;
a[i] = mp[ch];
// cout << a[i]<<" ";
}
// cout << endl;
int K = 1,M = n;
for(int k=1;k<=n;k++)
{
int m = calc(k);
if(m>=0&&m<M)
{
M = m; //选出最小的反转次数以及其对应的K
K = k;
}
}
cout << K<<" "<< M <<endl;
}