luogu P2697 寶石串

題目描述

有一種寶石串,由綠寶石和紅寶石串成,僅當綠寶石和紅寶石數目相同的時候,寶石串才最爲穩定,不易斷裂。安安想知道從給定的寶石串中,可以截取一段最長的穩定的寶石串,有多少顆寶石組成。請你幫助他。

綠寶石用‘G’表示,紅寶石用‘R’表示。

輸入輸出格式

輸入格式:
一行由G和R組成的字符串

輸出格式:
最長的穩定的寶石串有多少顆寶石組成

輸入輸出樣例

輸入樣例#1:

GRGGRG

輸出樣例#1:

4

說明

RGGR爲答案。

寶石數<=1000000


這道題看數據範圍不是O(n)就是O(nlogn),所以我們可以從數據範圍入手,顯然我們一般會從O(nlogn)這個複雜度分析;

O(nlogn)(WA):

顯然我們可以從二分入手,這樣子複雜度是O(nlogn)的,那我們會枚舉答案長度,然後進行二分,然後就會處理細節,比如爲了好處理,我們會讓’G’記爲1,’R’記爲0,這樣我們處理可以用^來快速處理顏色,但是打完會發現WA,那我們就要反思一下,爲什麼這個算法會WA;

因爲這個題目不滿足二分的性質,所以不行,但是在反思中,我們會發現“我們會讓’G’記爲1,’R’記爲0”這步處理,所以,我們可以想到一個別的方法來處理:’G’還是1,但’R’是-1,這樣如果有一段區間的’G”R’數量相等,那麼這段區間的和爲0;

所以,正確的算法是亂搞,複雜度是O(n);

O(n)(正解):

我們輸入時處理好1和-1,然後用一個for循環來記錄前綴和s,如果當前出現的前綴s和已經在此之前出現過,則說明從之前出現這個前綴和s的位置到現在這個位置中間的’G’和’R’的數量是相等的,所以這時候我們更新一下答案ans,最後輸出ans就好了;當然,如果前綴和s第一次出現,我們需要記錄下位置;


完整代碼:

#include<iostream>
#include<cstdio>
#define mid ((l+r)>>1)
#define II int
#define R register
#define I 2000010
using namespace std;


II wei[I],a[I];

II n,ans;


int main()
{
    R char p; R II now=0;
    while (scanf("%c",&p)!=EOF&&p!='\n') p=='G'? a[++n]=1: a[++n]=-1;
        //'G' is 1,'R' is -1;
    a[n+1]=n+n+25;
    a[n+2]=n+n+54;
    a[n+3]=n+n+46;
        //這裏可有可無;
    for(R II i=0;i<=n*2+12;i++) wei[i]=-1;
        //初始化每個點第一次出現的位置;
    wei[1]=0;wei[1+n]=0;
        //0第一次出現的位置是0,即沒有寶石的時候;
    for(R II i=1;i<=n;i++)
    {
        now+=a[i];
        if(wei[now+n+1]==-1) wei[now+n+1]=i;
          else ans=max(ans,i-wei[now+n+1]);
    }
    printf("%d\n",ans);
    return 0;
}

by pretend-fal;

END;

發佈了33 篇原創文章 · 獲贊 13 · 訪問量 1萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章