回文就是正反读都是一样的字符串,如aba, abba等
Input 输入有多组case,不超过120组,每组输入为一行小写英文字符a,b,c...y,z组成的字符串S
两组case之间由空行隔开(该空行不用处理)
字符串长度len <= 110000
Output 每一行一个整数x,对应一组case,表示该组case的字符串中所包含的最长回文长度.
Sample Input aaaa abab Sample Output 4 3
思路:马拉车模板体
#include<cstdio> #include<cstring> #include<algorithm> #include<iostream> #include<string> #include<vector> #include<stack> #include<bitset> #include<cstdlib> #include<cmath> #include<set> #include<list> #include<deque> #include<map> #include<queue> #define ll long long int using namespace std; inline ll gcd(ll a,ll b){return b?gcd(b,a%b):a;} inline ll lcm(ll a,ll b){return a/gcd(a,b)*b;} int moth[13]={0,31,28,31,30,31,30,31,31,30,31,30,31}; int dir[4][2]={1,0 ,0,1 ,-1,0 ,0,-1}; int dirs[8][2]={1,0 ,0,1 ,-1,0 ,0,-1, -1,-1 ,-1,1 ,1,-1 ,1,1}; const int inf=0x3f3f3f3f; const ll mod=1e9+7; int p[1000007]; //记录半径 void manacher(string s){ string ma=""; ma+='$'; ma+='#'; int len=s.length(); //预处理字符串 加#是为了让长度变为奇数(避免讨论奇偶) //二加$则是为了求字符串的起始位置 在博客中有相关叙述 for(int i=0;i<len;i++){ ma+=s[i]; ma+='#'; } int po=0; int mx=0; //po记录当前可以延伸到最右端的点 mx为长度 len=ma.length(); for(int i=0;i<len;i++){ p[i]=mx>i?min(p[2*po-i],mx-i):1; //关键代码 在博客中理解 while(ma[i+p[i]]==ma[i-p[i]]) p[i]++; if(i+p[i]>mx){ //更新 mx=i+p[i]; po=i; } } } int main(){ ios::sync_with_stdio(false); string s; while(cin>>s){ manacher(s); int len=s.length(); int ans=0; for(int i=0;i<2*len+2;i++) ans=max(ans,p[i]-1); //找最长的长度 cout<<ans<<endl; } return 0; }