cf Educational Codeforces Round 55 B. Vova and Trophies

原題:
B. Vova and Trophies
time limit per test2 seconds
memory limit per test256 megabytes
inputstandard input
outputstandard output
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.

Input
The first line contains one integer n (2≤n≤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.

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

Examples
input
10
GGGSGGGSGG
output
7
inputCopy
4
GGGG
output
4
input
3
SSS
output
0
Note
In the first example Vova has to swap trophies with indices 4 and 10. Thus he will obtain the sequence “GGGGGGGSGS”, the length of the longest subsegment of golden trophies is 7.

In the second example Vova can make no swaps at all. The length of the longest subsegment of golden trophies in the sequence is 4.

In the third example Vova cannot do anything to make the length of the longest subsegment of golden trophies in the sequence greater than 0.

中文:

有金獎盃G和銀獎盃S,現在給你n個獎盃和排放順序,現在讓你任意交換這些獎盃中的其中兩個位置,只交換一次,問你金獎盃最長能擺多少個?

代碼:

#include<bits/stdc++.h>
using namespace std;

int n;
string s;
typedef pair<int,int> pii;
vector<pii> vp;
map<int,int> start,en;

int main()
{
    ios::sync_with_stdio(false);
    while(cin>>n)
    {
        vp.clear();
        start.clear();
        en.clear();
        cin>>s;
        int st=0;
        int G=0,ans=0;
        for(int i=0;i<n;)
        {
            if(s[i]=='G')
            {
                st=i;
                while(s[i]=='G')
                {
                    G++;
                    i++;
                }
                vp.push_back(make_pair(st,i-1));
                ans=max(ans,i-st);
                start[st]=i-1;
                en[i-1]=st;
            }
            else
                i++;
        }
        if(vp.size()>1)
            ans=ans+1;
        int cnt,tmp;
        for(auto x:vp)
        {
            cnt=x.second-x.first+1;
            if(en.find(x.first-2)!=en.end())
            {
                tmp=x.first-1-en[x.first-2];
                if(tmp+cnt<G)
                    ans=max(ans,tmp+cnt+1);
                else
                    ans=max(ans,tmp+cnt);
            }
            if(start.find(x.second+2)!=start.end())
            {
                tmp=start[x.second+2]-x.second-1;
                if(tmp+cnt<G)
                    ans=max(ans,tmp+cnt+1);
                else
                    ans=max(ans,tmp+cnt);
            }
        }
        cout<<ans<<endl;
    }

    return 0;
}

思路:

首先把所有金獎盃的序列都單獨拿出來,如果金獎盃的序列只有一個,那麼答案就是這個序列的長度。
如果金獎盃的序列有多個,那麼要分幾種情況。

第一種,兩個金獎盃序列之間隔了一個銀獎盃,那麼可以把其中一個序列末尾的金獎盃序列和這個銀獎盃調換位置,這樣就連成了一個序列,找出所有這種情況中最長的即可。

第二種,如果兩個金獎盃序列之間隔着超過一個銀獎盃,那麼就是最長的金獎盃序列後面或者前面的銀獎盃和另外一個金獎盃序列中的一個獎盃交換位置,得到的結果就是最長的那個金獎盃序列的長度加一。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章