E. String Multiplication(想法)

原题: http://codeforces.com/contest/1131/problem/E

题意:

定义字符串 S T = T + S 1 ( ) + T + . . . + S n + T S*T=T+S_1(第一个字母)+T+...+S_n+T ,例如 a c b = b a b c b ac*b=babcb ,现在给出n个串 P 1 . . . P n P_1...P_n ,求目标串 ( . . ( P 1 P 2 ) P 3 ) . . . ) P n (..(P_1*P_2)*P_3)...)*P_n 中,连续相同字符的个数的最大值( a b b b c = 3 abbbc=3 )。

解析:

可以分析出 ( . . ( P 1 P 2 ) P 3 ) . . . ) P n = P 1 ( . . . ( P n 2 ( P n 1 P n ) . . . ) (..(P_1*P_2)*P_3)...)*P_n=P_1*(...(P_{n-2}*(P_{n-1}*P_n)...) ,即先从后面处理,这样有什么好处? S T S*T 的意思其实是把 T T 插入到 S S 的各个位置,连接两块S的只有一个字符。这样最明显的优势为:只要 T T 已经非同一字符(至少两种字符),那么 S T S*T 的左端连续相同字符和右端连续字符,不管在种类上还是长度上都和 T T 一样。

考虑可能变长的部分:

在这里插入图片描述
如果两边字符相同且等于x,那么长度为l+1+r。其他情况可自行考虑。

如果一直相同更好办, s u m ( ) = l e n ( ) + ( l e n + 1 ) s u m sum(已积累长度)=len(当前段长度)+(len+1)*sum

注意点:

  • 需要用最后一个串的最长连续相同子串更新答案。
  • 第一次出现不同时,假设累积串为 a a a aaa ,当前串为 b a a b baab ,那么 a a a a a a a a a a a aaa|a|aaa|a|aaa 需要更新答案。

代码:

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

string x[100009];

int main(){
    int n;cin>>n;
    for(int i=1;i<=n;i++){
        cin>>x[i];
    }
    int l=0,r=0;
    int ans=1;
    char L=x[n][0],R=x[n][x[n].length()-1];
    //***************考虑第一个串
    int co=1;
    for(int i=1;i<x[n].length();i++){
        if(x[n][i]==x[n][i-1])co++;
        else {
            ans=max(ans,co);
            co=1;
        }
    }
    ans=max(ans,co);


    int sum=0;
    if(x[n].length()==1){
        sum=1;
    }
    else{
        int i;
        for(i=1;i<x[n].length();i++){
            if(x[n][i]!=x[n][0])break;
        }
        i--;
        if(i==x[n].length()-1){
            sum=x[n].length();
        }
        else{
            l=i+1;
            for(i=x[n].length()-2;;i--){
                if(x[n][i]!=R)
                    break;
            }
            r=x[n].length()-1-i;
        }
    }
    ans=max(ans,max(sum,max(l,r)));
    //***************
    
    for(int i=n-1;i>=1;i--){
        if(!l){//还是全部相同
            int f=0;
            for(int j=0;j<x[i].length();j++){
                if(x[i][j]!=L){
                    f=1;
                    l=j+(j+1)*sum;
                    break;
                }
            }
            if(f){
                for(int j=x[i].length()-1;;j--){
                    if(x[i][j]!=R){
                        r=x[i].length()-1-j;
                        r=r+(r+1)*sum;
                        break;
                    }
                }
                //第一次出现不同时
                int co=0;
                for(int j=0;j<x[i].length();j++){
                    if(x[i][j]==L)co++;
                    else {
                        ans=max(ans,co+(co+1)*sum);
                        co=0;
                    }
                }
                ans=max(ans,co+(co+1)*sum);
            }
            else{
                sum=x[i].length()+(x[i].length()+1)*sum;
            }
        }
        else{
            for(int j=0;j<x[i].length();j++){
                if(x[i][j]==L){
                    if(L==R){
                        ans=max(ans,l+r+1);
                    }
                    else{
                        ans=max(ans,l+1);
                    }
                }
                else if(x[i][j]==R){
                    ans=max(ans,r+1);
                }
            }
        }
    }
    ans=max(ans,max(sum,max(l,r)));
    printf("%d\n",ans);
}

猜你喜欢

转载自blog.csdn.net/jk_chen_acmer/article/details/87904929
今日推荐