Codeforces Round #541 (Div. 2) E. String Multiplication//思维(暴力)

博客围绕https://codeforces.com/contest/1131/problem/E展开,讲述将s2插入s1、s3插入新字符s后求最长相同连续块的问题。推导出从1 - n操作等效于从n - 1操作,每次串左右端点相同,通过维护左右端最长相同块更新答案,还需注意特殊情况及sn对答案的影响。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

https://codeforces.com/contest/1131/problem/E 

 

 题意,将s2插入到s1的每一个字符中间形成新字符s,s3再插入到s的每一个字符中间,求最长的相同的连续块。

推了一下发现从1-n操作可以等效于从n-1操作。

而每次的串的左右端点都是相同的。

直接维护最左端和最右端的最长相同块,不断更新答案。

注意处理整段相同和不相同的情况即可。

勿忘sn的对答案的影响。

#include<bits/stdc++.h>
using namespace std;
#define LL long long
const int mod = 1e9+7;
const int maxn = 1e5+5;
vector<char>s[maxn];
int fmaxsub(int i,char c){
    int re=0;int x=0;
    for(int j=0;j<s[i].size();j++){
        if(s[i][j]==c) x++;
        else {
            re=max(x,re);
            x=0;
        }
    }
    return max(re,x);
}
int fl(int i,char c){  //左到右有几个
    int re=-1;
    while(re+1<(int)s[i].size()&&s[i][re+1]==c)re++;
    return re+1;
}
int fr(int i,char c){
    int re=s[i].size();
    while(re-1>=0&&s[i][re-1]==c) re--;
    return s[i].size()-re;
}
int main(){
    ios::sync_with_stdio(false);
    int n;cin>>n;
    for(int i=1;i<=n;i++){
        char ts[maxn];cin>>ts;int le=strlen(ts);
        for(int j=0;j<le;j++){
            s[i].push_back(ts[j]);
        }
    }
    int ans=0;
    char lc=s[n][0],rc=s[n][s[n].size()-1];
    int l=fl(n,lc),r=fr(n,rc);  //sn
    bool same=1; 
    for(int i=97;i<=122;i++)                                                                                 
		ans=max(ans,fmaxsub(n,i));
    if(l!=s[n].size())same=0;   
    for(int i=n-1;i>=1;i--){
        if(same==1){                  //整段相同情况
            int fms=fmaxsub(i,rc);
            ans=max(ans,(l+1)*(fms)+l);
            int countl=fl(i,lc);
            l=(l+1)*(countl)+l;
            int countr=fr(i,rc);
            r=(r+1)*(countr)+r;
            if(fms<s[i].size()) same=0;
        }
        else {                     //不同
            for(int j=0;j<(int)s[i].size();j++){
                int a=0;int b=0;
                if(rc==s[i][j]){
                    a=r;
                }
                if(lc==s[i][j]){
                    b=l;
                }
                ans=max(ans,a+b+1);
            }
        }
    }
    cout<<max(ans,max(l,r));
    return 0;
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值