- 可算明白了..
BBFBFBB
我们到达第三个F,我们需反转。标记一下在3出反转了(vis[3]=1). 对以后的影响是+1.,用sum记载影响程度即sum=1;
我们到达第四个,虽然是B,但是收到前面影响(sum==1),也就是变成F了。我们需要反转。标记vis[4]=1. ,sum再+1.即sum=2;
也就是第五个会受到sum=2个影响。以此类推。 不过到达第i个时,第i个不会受到超出k的反转的影响。所以说if(i-k+1>0) sum-=vis[i-k+1]. 这个vis不是0就是1,这样来控制sum。
到了最后一组了,就没办法翻转了,如果剩余的是正的,那就继续往下周。如果不是正的,就不要翻转了,而是直接输出-1.
-
-
- #include <iostream>
- #include <cstdio>
- #include <cstring>
- using namespace std;
- const int maxn = 5000 + 5;
- int dir[maxn], n, f[maxn]; //f[i]=1:面向后方 f[i]=0面向前方
- int compute(int k) //计算连续反转k头牛需要几次操作?
- {
- memset(f, 0, sizeof(f));
- int res = 0, sum = 0;
- for(int i = 0; i+k-1 <= n-1; i++){
- if((sum + dir[i]) & 1){
- 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((sum + dir[i]) & 1) return -1;
- if(i - k + 1 >= 0) sum -= f[i-k+1];
- }
- return res;
- }
- int main()
- {
- //freopen("in.txt", "r", stdin);
- while(~scanf("%d", &n)){
- char tmp[5];
- memset(dir, 0, sizeof(dir));
- for(int i = 0; i < n; i++){
- cin >> tmp;
- if(tmp[0] == 'B') dir[i] = 1;
- else dir[i] = 0;
- }
- int ans_k = 1, ans_cnt = n;
- for(int k = 1; k <= n; k++){
- int cnt = compute(k);
- if(cnt < ans_cnt && cnt >= 0){
- ans_cnt = cnt;
- ans_k = k;
- }
- }
- printf("%d %d\n", ans_k, ans_cnt);
- }
- return 0;
- }