CF1082B Vova and Trophies 题解

CF1082B Vova and Trophies 题解

瞎搞题,推荐的,一看是道水题,就随手A了……

题目描述

Vova has won \(n\)trophies in different competitions. Each trophy is either golden or silver. The trophies are arranged in a row.

The beauty of the arrangement is the length of the longest subsegment consisting of golden trophies. Vova wants to swap two trophies (not necessarily adjacent ones) to make the arrangement as beautiful as possible — that means, to maximize the length of the longest such subsegment.

Help Vova! Tell him the maximum possible beauty of the arrangement if he is allowed to do at most one swap.

输入格式

The first line contains one integer \(n( 2 \le n \le 10^5)\) — the number of trophies.

The second line contains \(n\) characters, each of them is either \(G\) or \(S\). If the $ i -th$ character is \(G\), then the \(i -th\) trophy is a golden one, otherwise it's a silver trophy.

输出格式

Print the maximum possible length of a subsegment of golden trophies, if Vova is allowed to do at most one swap.

题解

单调队列
我的想法是从左往右搞一个前缀和,记录一下当前有几个\(G\)
然后我们思考,能让一个\(G\)去替换\(S\)的条件是什么:
是至少有一个\(G\)没被我们选中,如图

想要让倒数第三个格子变成\(G\),就必须有一个其他格子是\(G\),比如\(1\)号格子
那么可以分类讨论一哈子

  1. 如果当前有至少一个\(G\)没被选中,我们就可以容忍在某一段序列里出现少于等于1个\(S\)

如图,绿色是我们已选中的序列,序列外有一\(G\),则可以替换
2.如果当前已选中所有的\(G\),那我们就不能从某个地方抽调一个\(G\)过来替换掉\(S\)

若为该情况则不可以,因为已经没有多余的\(G\)来替换了
那么这个东西的实现我们就可以用一下单调队列
并不需要真的搞个队列,模拟一下就行
首先先设一个指针\(now\)指向零,然后读入
读入的时候如果读入的是\(G\),那么存为\(1\),否则存为\(0\)
这样前缀和数组\(sum[i]\)就可以统计出在\(i\)位置前有多少个\(G\)
\(sum[i] - sum[now]\)就是当前队列里有多少个\(G\)
我们比较与\(sum[i] - sum[now]\)与当前队列里的奖牌数,就可以根据上面说的两种情况做出特判
大水题……

#include<bits/stdc++.h>
using namespace std;
#define rint register int 
int n, a[100010], sum[100010], now, ans, tot;
int main( void ){
    cin >> n;
    char ch;
    for( rint i = 1; i <= n; i++ ){
        cin >> ch;
        if( ch == 'G' ){
            a[i] = 1; tot++;
        } else a[i] = 0;
        sum[i] = sum[i - 1] + a[i]; 
    }
    for( rint i = 1; i <= n; i++ ){
        if( sum[i] - sum[now] != tot ){
            while( sum[i] - sum[now] < i - now - 1 && now <= i ) now++; ans = max( ans, i - now );
        }else{
            while( sum[i] - sum[now] < i - now && now <= i ) now++; ans = max( ans, i - now ); 
        }       
    }
    cout << ans;
    return 0;
}

猜你喜欢

转载自www.cnblogs.com/with6676/p/11732940.html