题意:求最大回文子串,(必须是镜像字母)。
题目链接:Gym - 101350I
思路:直接暴力匹配每一位上的最长回文子串,匹配的方式就是以一个字母为中心向两边延伸看是否相同。
看到这题还有其他做法,就是马拉车算法,我就去学习了一波,我贴在了最下面。
然后是博主的原文Gym - 101350I Mirrored String II 求给定字符的最长回文感谢博主
然后我就总结了一下马拉车算法马拉车(Manacher)算法(求最大回文子串)
#include<bits/stdc++.h>
using namespace std;
char mod[] = {'A', 'H', 'I', 'M', 'O', 'T', 'U', 'V', 'W', 'X', 'Y'};
int len2 = strlen(mod);
bool judge(char x)
{
for(int i = 0; i < len2; i++)
{
if(x == mod[i]) return true;
}
return false;
}
int main()
{
int n;
char s[1010];
cin >> n;
int odd[1010],even[1010];
while(n--)
{
cin >> s;
int len = strlen(s);
int ans = -1;
memset(odd,0,sizeof(odd));
memset(even,0,sizeof(even));
for(int i = 0; i < len; i++)
{
if(judge(s[i]))//先判断是否是镜像字母
{
odd[i] = 1;//每一位上都有两种可能,奇数和偶数
int l = i-1;
int r = i+1;
while(l >= 0 && r < len)
{
if(judge(s[l]) && s[l] == s[r]) l--,r++,odd[i] += 2;
else break;
}
if(judge(s[i+1]) && s[i+1] == s[i])
{
even[i] = 2;
l = i-1;
r = i+2;
while(l >= 0 && r < len)
{
if(judge(s[l]) && s[l] == s[r]) l--,r++,even[i] += 2;
else break;
}
}
}
ans = max(ans,max(odd[i],even[i]));//找最大就可以刻
}
cout << ans << endl;
}
return 0;
}
#include <bits/stdc++.h>
using namespace std;
const int MAXN=210000;
char ch[]={'A', 'H', 'I', 'M', 'O', 'T', 'U', 'V', 'W', 'X', 'Y'};
char ch2[]={'A', 'H', 'I', 'M', 'O', 'T', 'U', 'V', 'W', 'X', 'Y', '#'};
struct Manacher{
int Ma[MAXN*2];
int Mp[MAXN*2];
int Mx[MAXN*2];
int len;
double ave;
int l;
int ans;
void manachar(int s[],int len){
l=0;ans=0;
Ma[l++]='$';
Ma[l++]='#';
for(int i=0; i<len; i++)
{
Ma[l++]=s[i];
Ma[l++]='#';
}
Ma[l]=0;
int mx=0,id=0;
int pp=strlen(ch2);
for(int i=0; i<l; i++)
{
ave++;
Mp[i]=mx>i?min(Mp[2*id-i],mx-i):1;
while(Ma[i+Mp[i]]==Ma[i-Mp[i]]){
Mp[i]++;
ave++;
}
if(i+Mp[i]>mx)
{
mx=i+Mp[i];
id=i;
}
Mx[i]=mx;
for(int j=0;j<pp;j++)
if(Ma[i]==ch2[j]){
ans=max(ans,Mp[i]-1);break;
}
}
ave/=len;
}
};
Manacher man;
char buf[MAXN];
int buff[MAXN];
int T;
int main(){
cin>>T;
while(T--){
getchar();
scanf("%s",buf);
int len=strlen(buf);
int len2=strlen(ch);
int ppp=128;
bool flag;
for(int i=0;i<len;i++){
flag=0;
for(int j=0;j<len2;j++)
if(buf[i]==ch[j]){
flag=1;
break;
}
if(!flag)
buf[i]=++ppp;
}
for(int i=0;i<len;i++)
buff[i]=buf[i];
man.manachar(buff,len);
cout<<man.ans<<endl;
}
}