HDU - 3068 最长回文(manacher)
生活随笔
收集整理的這篇文章主要介紹了
HDU - 3068 最长回文(manacher)
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
HDU - 3068 最長回文
Submit?Status Description 給出一個只由小寫英文字符a,b,c...y,z組成的字符串S,求S中最長回文串的長度.?回文就是正反讀都是一樣的字符串,如aba, abba等 Input 輸入有多組case,不超過120組,每組輸入為一行小寫英文字符a,b,c...y,z組成的字符串S?兩組case之間由空行隔開(該空行不用處理)? 字符串長度len <= 110000 Output 每一行一個整數x,對應一組case,表示該組case的字符串中所包含的最長回文長度.?Sample Input aaaaababSample Output 4 3Source 2009 Multi-University Training Contest 16 - Host by NIT |
題目要求求出最長回文子串,是一道manacher的模板題。
我們先講一下manacher,我們先處理一下字符串,把字符串處理成#a#a#這樣的格式,比如abcd處理成#a#b#c#d#,這樣的好處是解決了判斷回文串是奇數和偶數的問題,把回文串強制變成奇數。接下來,定義一個p[]數組,p[i]代表以節點i為中心的最長回文串的半徑。例如aaaa這個字符串,p[0]=p[3]=1,p[1]=p[2]=2。同時我們定義一個變量mx和id,mx代表當前判斷過的回文子串最長延伸(往右)到哪里,可以理解為當前判斷過的回文子串到達的最大下標。而id代表當前更新的mx值所對應的回文串的中心的下標。如果不是很清楚可以直接看下代碼。剩下部分直接看代碼注釋吧。最好自己在紙上畫一下
#include <iostream> #include <cstdio> #include <cstring> #include <cmath> #include <algorithm> #include <vector> #include <queue> #include <stack> #include <map> #include <set> #define X first #define Y second #define clr(u,v); memset(u,v,sizeof(u)); using namespace std; typedef long long ll; typedef pair<int,int> pii; const int maxn=2e5+10;//注意開兩倍大小 const int INF=0x3f3f3f3f; char s[maxn],str[maxn];//s為原字符串,str為處理后的字符串 int p[maxn];//p[i]代表以i為中心的回文串的最長半徑 int len1,len2;//分別代表s的長度和str的長度 void init()//預處理出str {len1=strlen(s);str[0]='$';//在首位加一個特殊字符,防止越界str[1]='#';for (int i=0;i<len1;i++){str[2*i+2]=s[i];str[2*i+3]='#';}len2=len1*2+2;str[len2]='\0';//不能和首位字符一樣 } void manacher() {int mx=0,id=0;for (int i=1;i<len2;i++){if (mx>i) //如果當前的i在mx以內,說明i為我們之前求的回文串的范圍里面p[i]=min(p[2*id-i],mx-i);//2*id-i代表i關于id對稱的下標,我們前面求出他是回文串,因此具備了對稱性,而2*id-i一定小于i,我們的i是從左到右掃描的,所以p[2*id-i]一定處理出來了,所以我們可以直接用p[2*id-i]的值,但是他不能超過mx-i,因為超過mx值我們就不能保證它是回文串,所以取二者最小else p[i]=1;//如果i不在回文串的范圍內,則初始化p[i]=1;for (;str[i-p[i]]==str[i+p[i]];p[i]++);//暴力往兩邊匹配,找到以i為中心的最長回文串if (mx<i+p[i])更新mx值和id值{mx=i+p[i];id=i;}} } int solve() {int ans=0;for (int i=1;i<len2;i++)if (ans<p[i]) ans=p[i];//找最大的p[i]就是答案return ans-1; } int main() {while (~scanf("%s",s)){init();manacher();printf("%d\n",solve());}return 0; }
?
轉載于:https://www.cnblogs.com/scaugsh/p/5964508.html
總結
以上是生活随笔為你收集整理的HDU - 3068 最长回文(manacher)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: USACO 2.1 健康的好斯坦奶牛 (
- 下一篇: 板邓:wordpress建站不得不知的安