#1032 : 最長迴文子串
描述
小Hi和小Ho是一對好朋友,出生在信息化社會的他們對編程產生了莫大的興趣,他們約定好互相幫助,在編程的學習道路上一同前進。
這一天,他們遇到了一連串的字符串,於是小Hi就向小Ho提出了那個經典的問題:“小Ho,你能不能分別在這些字符串中找到它們每一個的最長迴文子串呢?”
小Ho奇怪的問道:“什麼叫做最長迴文子串呢?”
小Hi回答道:“一個字符串中連續的一段就是這個字符串的子串,而回文串指的是12421這種從前往後讀和從後往前讀一模一樣的字符串,所以最長迴文子串的意思就是這個字符串中最長的身爲迴文串的子串啦~”
小Ho道:“原來如此!那麼我該怎麼得到這些字符串呢?我又應該怎麼告訴你我所計算出的最長迴文子串呢?
小Hi笑着說道:“這個很容易啦,你只需要寫一個程序,先從標準輸入讀取一個整數N(N<=30),代表我給你的字符串的個數,然後接下來的就是我要給你的那N個字符串(字符串長度<=10^6)啦。而你要告訴我你的答案的話,只要將你計算出的最長迴文子串的長度按照我給你的順序依次輸出到標準輸出就可以了!你看這就是一個例子。”
提示一提示二提示三提示四3 abababa aaaabaa acacdas樣例輸出
7 5 3
#include <bits/stdc++.h> using namespace std; typedef long long ll ; typedef double dl ; #define INF 0x7f const int maxn =1e6+5; #define f(i,l,r) for(int i=l;i<=r;++i) #define g(i,l,r) for(int i=l;i>=r;--i) char str[maxn],s[maxn<<1]; int p[maxn<<1]; void manacher() { memset(p,0,sizeof(p)); memset(s,0,sizeof(s)); int l=-1; int n =strlen(str); f(i,0,n-1)s[++l]='#',s[++l]=str[i]; s[++l]='#'; int mx=-1,id=0; int ans=0; f(i,2,l-1) { if(mx+id>i) p[i]=min(p[id*2-i],mx+id-i); while(i-p[i]-1>=0&&i+p[i]+1<=l &&s[i+p[i]+1]==s[i-p[i]-1]) p[i]++; if(mx+id<i+p[i]) id=i,mx=p[i]; ans=max(ans,p[i]); } cout<<ans<<endl; } int main() { freopen("in","r",stdin); int n; cin>>n; while(n--) { cin>>str; manacher(); } return 0; }