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;
}