题目链接
题目大意
找最长的回文串
思路
最简单的Manacher/马拉车算法
代码
#include <iostream>
#include <string>
#include <cstring>
using namespace std;
int main()
{
char s[111111];
while(~scanf("%s",s))
{
//标记一下
int len = strlen(s);
if(len ==1) //1的时候单独处理
{
cout<<1<<endl;
continue;
}
char ss[222222];
memset(ss,0,sizeof(ss)); //每次都要清空,要不然在算长度时会有影响
ss[0] = '@';
int j=1;
for(int i=0; i<len; i++)
{
ss[j] = '#';
j++;
ss[j] = s[i];
j++;
}
ss[j] = '#';
j++;
ss[j] = '%';
// cout<<ss<<endl;
//求回文半径数组~
int len1 = strlen(ss);
int p[222222];
memset(p,0,sizeof(p));
int c=0,r=0; //中心/右半径
for(int i=1; i<len1-1; i++)
{
int i_mir = c - (i-c); //对称点
int diff = r - i; //差值
if(diff >= 0)
{
if(p[i_mir] < diff)
p[i] = p[i_mir];
else
{
p[i] = diff;
while(ss[i+p[i]+1] == ss[i-p[i]-1])
{
// cout<<ss[i+p[i]+1] <<"and" <<ss[i-p[i]-1]<<endl;
p[i]++;
}
c = i;
r = i +p[i];
}
}
else
{
p[i] = 0;
while(ss[i+p[i]+1] == ss[i-p[i]-1])
{
// cout<<ss[i+p[i]+1] <<"and" <<ss[i-p[i]-1]<<endl;
p[i]++;
}
c = i;
r = i +p[i];
}
}
//找最长的
int maxlen = 0;
for(int i=1; i<len1-1; i++)
{
if(p[i] > maxlen)
{
if(p[i]==1 && i%2==0)
continue;
else
maxlen = p[i];
}
// cout<<p[i]<<' ';
}
// cout<<endl;
cout<<maxlen<<endl;
char ch = getchar(); //注意看题目要求,有一个空行~
}
return 0;
}
注意
都写在备注里了( ̄︶ ̄*))