• <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>
            C++分析研究  
            C++
            日歷
            <2013年11月>
            272829303112
            3456789
            10111213141516
            17181920212223
            24252627282930
            1234567
            統(tǒng)計(jì)
            • 隨筆 - 92
            • 文章 - 4
            • 評(píng)論 - 4
            • 引用 - 0

            導(dǎo)航

            常用鏈接

            留言簿

            隨筆檔案

            文章檔案

            搜索

            •  

            最新評(píng)論

            閱讀排行榜

            評(píng)論排行榜

             
              題意:給出一個(gè)字符串,求出最長(zhǎng)回文字串。
             
               思路:一開始我直接上了后綴數(shù)組DC3的解法,然后MLE了。看了DISCUSS發(fā)現(xiàn)還有一種計(jì)算回文字串更加優(yōu)越的算法,就是manacher算法。就去學(xué)習(xí)了一下,
             
               這個(gè)算法要解決的就是一個(gè)字符串中最長(zhǎng)的回文子串有多長(zhǎng)。這個(gè)算法可以在O(n)的時(shí)間復(fù)雜度內(nèi)既線性時(shí)間復(fù)雜度的情況下,求出以每個(gè)字符為中心的最長(zhǎng)回文有多長(zhǎng),
             
               這個(gè)算法有一個(gè)很巧妙的地方,它把奇數(shù)的回文串和偶數(shù)的回文串統(tǒng)一起來考慮了。這一點(diǎn)一直是在做回文串問題中時(shí)比較煩的地方。這個(gè)算法還有一個(gè)很好的地方就是充分利用了字符匹配的特殊性,避免了大量不必要的重復(fù)匹配。
             
               算法大致過程是這樣。先在每?jī)蓚€(gè)相鄰字符中間插入一個(gè)分隔符,當(dāng)然這個(gè)分隔符要在原串中沒有出現(xiàn)過。一般可以用'#'分隔。這樣就非常巧妙的將奇數(shù)長(zhǎng)度回文串與偶數(shù)長(zhǎng)度回文串統(tǒng)一起來考慮了(見下面的一個(gè)例子,回文串長(zhǎng)度全為奇數(shù)了),然后用一個(gè)輔助數(shù)組P記錄以每個(gè)字符為中心的最長(zhǎng)回文串的信息。P[id]記錄的是以字符str[id]為中心的最長(zhǎng)回文串,當(dāng)以str[id]為第一個(gè)字符,這個(gè)最長(zhǎng)回文串向右延伸了P[id]個(gè)字符。
               原串: w aa bwsw f d
               新串: # w# a # a # b# w # s # w # f # d #
               輔助數(shù)組P: 1 2 1 2 3 2 1 2 1 2 1 4 1 2 1 2 1 2 1
               這里有一個(gè)很好的性質(zhì),P[id]-1就是該回文子串在原串中的長(zhǎng)度(包括'#')。如果這里不是特別清楚,可以自己拿出紙來畫一畫,自己體會(huì)體會(huì)。當(dāng)然這里可能每個(gè)人寫法不盡相同,不過我想大致思路應(yīng)該是一樣的吧。
               好,我們繼續(xù)。現(xiàn)在的關(guān)鍵問題就在于怎么在O(n)時(shí)間復(fù)雜度內(nèi)求出P數(shù)組了。只要把這個(gè)P數(shù)組求出來,最長(zhǎng)回文子串就可以直接掃一遍得出來了sat答案
               由于這個(gè)算法是線性從前往后掃的。那么當(dāng)我們準(zhǔn)備求P[i]的時(shí)候,i以前的P[j]我們是已經(jīng)得到了的。我們用mx記在i之前的回文串中,延伸至最右端的位置。同時(shí)用id這個(gè)變量記下取得這個(gè)最優(yōu)mx時(shí)的id值。(注:為了防止字符比較的時(shí)候越界,我在這個(gè)加了'#'的字符串之前還加了另一個(gè)特殊字符'$',故我的新串下標(biāo)是從1開始的)托福答案
               /*****************************************************************************************************************************************************************/
               CODE:
               #include <set>
               #include <map>
               #include <stack>
               #include <cmath>
               #include <queue>
               #include <cstdio>
               #include <string>
               #include <vector>
               #include <iomanip>
               #include <cstring>
               #include <iostream>
               #include <algorithm>
               #define Max 2505
               #define FI first
               #define SE second
               #define ll long long
               #define PI acos(-1.0)
               #define inf 0x3fffffff
               #define LL(x) ( x 《 1 )
               #define bug puts("here")
               #define PII pair<int,int>
               #define RR(x) ( x 《 1 | 1 )
               #define mp(a,b) make_pair(a,b)
               #define mem(a,b) memset(a,b,sizeof(a))
               #define REP(i,s,t) for( int i = ( s ) ; i <= ( t ) ; ++ i )
               #define N 2000055
               using namespace std;
               char s[N] ;
               char str[N] ;
               int rad[N] ;
               int manacher () {
               int len = strlen(s) ;
               int max = 0;
               str[0] = '$';
               str[1] = '#';
               int i = 0 ;
             
               for (; i < len; i++) {
               str[i * 2 + 2] = s[i];
               str[i * 2 + 3] = '#';
               }
               str[2 * len + 2] = 0;
               for (int i = 1; i < 2 * len + 2 ; i++) {
               rad[i] = 0;
               }
               int id = 0;
               for (i = 1; i < 2 * len + 2; i++) {
               if (max > i)
               rad[i] = min(rad[2 * id - i], rad[id] + id - i) ;
               else
               rad[i] = 1 ;
               while (str[i + rad[i]] == str[i - rad[i]])
               rad[i] ++ ;
               if (rad[i] + i > max) {
               max = rad[i] + i;
               id = i;
               }
               }
               int mx = 0;
               for (i = 1; i < 2 * len + 2 ; i++) {
               if (mx < rad[i] - 1)
               mx = rad[i] - 1;
               }
               return mx;
               }
               int main() {
               int ca = 0 ;
               while(scanf("%s",s) != EOF) {
               if(strcmp(s , "END") == 0)break ;
               printf("Case %d: " , ++ ca) ;
               printf("%d\n",manacher()) ;
               }
               return 0 ;
               }
            posted on 2013-11-17 12:19 HAOSOLA 閱讀(472) 評(píng)論(0)  編輯 收藏 引用

            只有注冊(cè)用戶登錄后才能發(fā)表評(píng)論。
            網(wǎng)站導(dǎo)航: 博客園   IT新聞   BlogJava   博問   Chat2DB   管理


             
            Copyright © HAOSOLA Powered by: 博客園 模板提供:滬江博客
            PK10開獎(jiǎng) PK10開獎(jiǎng)
            国产三级久久久精品麻豆三级| 久久婷婷是五月综合色狠狠| AV无码久久久久不卡网站下载| 久久99国内精品自在现线| 久久精品人人做人人爽电影蜜月 | 亚洲中文久久精品无码ww16| 伊人久久大香线焦AV综合影院| 国内精品久久久久影院日本| 国产99久久久国产精免费| 2019久久久高清456| 国产成人久久激情91| 2021国内久久精品| 国产伊人久久| 99久久国语露脸精品国产| 国内精品伊人久久久久妇| 一本久久久久久久| 韩国免费A级毛片久久| 国产成人综合久久精品红| 国产2021久久精品| 日韩AV无码久久一区二区| 亚洲精品美女久久久久99小说| 久久久国产精品网站| 亚洲欧美成人综合久久久| 四虎国产精品成人免费久久| yellow中文字幕久久网| 久久se精品一区二区| 浪潮AV色综合久久天堂| 久久久久久精品免费免费自慰| 人妻无码久久精品| 人妻丰满?V无码久久不卡| 亚洲精品乱码久久久久久蜜桃 | 久久天天躁夜夜躁狠狠| 欧美成a人片免费看久久| 久久综合伊人77777| 久久夜色撩人精品国产| 久久99久久无码毛片一区二区| 国产精品欧美久久久久无广告| 国产AV影片久久久久久| 国产激情久久久久影院小草| 久久99国产一区二区三区| 久久久久久无码国产精品中文字幕 |