美丽区间

题目链接

戳这

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;
}
posted @ 2024-03-18 14:57  撤云  阅读(61)  评论(0编辑  收藏  举报
……