日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

HDU - 3068 最长回文(manacher)

發布時間:2025/3/21 编程问答 21 豆豆
生活随笔 收集整理的這篇文章主要介紹了 HDU - 3068 最长回文(manacher) 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
HDU - 3068 最長回文
Time Limit:?2000MS?Memory Limit:?32768KB?64bit IO Format:?%I64d & %I64u

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

aaaaabab

Sample Output

4 3

Source

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)的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。