美丽区间
题目链接
Solution
因为n很小所以可以 n方枚举左右端点,然后实际上就是判断前面一半将69交换后是否是个 回文且这个 回文不存在反转后没意义的数,对于那几个翻转后没意义的数字随便用字母代替即可,对于前缀和后缀分别哈希然后判断是否相等即可。
#include<bits/stdc++.h>
#define int long long
using namespace std;
const int mod=1e9+7,base=233;
string s;
string s1;
int sum[1000010];
int sum1[1000010];
int js[1001];
int bj[1000010];
int jc[1000010];
int check1(int x,int now){
return (sum[x+now]-sum[now]*jc[x]%mod+mod)%mod;
}
int check2(int x,int now){
return (sum1[now-x+1]-sum1[now+1]*jc[x]%mod+mod)%mod;
}
signed main(){
int n;
cin>>n;
for(int i=1;i<=n;i++){
cin>>s,s1+=s;
js[i]=js[i-1]+s.size();
}
jc[0]=1;
for(int i=1;i<=s1.size();i++)
jc[i]=jc[i-1]*base%mod;
for(int i=1;i<=s1.size();i++){
if(s1[i-1]=='6') sum[i]=(sum[i-1]*base%mod+9)%mod;
else if(s1[i-1]=='9') sum[i]=(sum[i-1]*base%mod+6)%mod;
else if(s1[i-1]=='1'||s1[i-1]=='8'||s1[i-1]=='0') sum[i]=(sum[i-1]*base%mod+s1[i-1]-'0')%mod;
else sum[i]=(sum[i-1]*base%mod+10)%mod;
}
for(int i=s1.size();i>=1;i--) sum1[i]=(sum1[i+1]*base%mod+s1[i-1]-'0')%mod;
int maxx=0;
for(int i=1;i<=n;i++)
for(int j=i;j<=n;j++){
int ans=js[j]-js[i-1];
ans=(ans+1)/2;
if(check1(ans,js[i-1])==check2(ans,js[j]))
maxx=max(j-i+1,maxx);
}
cout<<maxx;
}