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;
}
原文地址:https://www.cnblogs.com/fxh0707/p/14615703.html