P2697 宝石串

思路

将'G'看成\(-1\),'R'看成\(+1\),要求最长的子串,使得子串中‘G’和‘R'的数量相等,则转化为求两个下标\(i\)\(j\),使得前缀和\(sum[j]-sum[i-1]=0\),即\(sum[j] == sum[i-1]\)

开一个\(pos\)数组记录每个\(sum[i]\)第一次出现的位置,之后对每个位置\(i\),如果\(sum[i]\)未出现过,则将\(sum[i]\)的位置记为\(i\),否则说明\(sum[i]\)出现过,更新答案。(为什么记录第一次?保证最长子串!)

注意点

\(0\)第一次出现的位置为下标\(0\),这是由于前缀和数组中\(sum[0]=0\)

const int N=1e6+10;
char s[N];
int pos[N<<1];
int n;

int main()
{
    memset(pos,-1,sizeof pos);

    scanf("%s",s+1);

    int n=strlen(s+1);
    int sum=0,res=0;
    pos[0+n]=0;
    for(int i=1;i<=n;i++)
    {
        if(s[i] == 'G') sum--;
        else sum++;
        if(pos[sum+n] == -1)
            pos[sum+n]=i;
        else
            res=max(res,i-pos[sum+n]);
    }

    cout<<res<<endl;

    //system("pause");
    return 0;
}
posted @ 2021-04-04 10:19  Dazzling!  阅读(65)  评论(0编辑  收藏  举报