• <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++
            日歷
            <2014年1月>
            2930311234
            567891011
            12131415161718
            19202122232425
            2627282930311
            2345678
            統(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)一起來(lái)考慮了。這一點(diǎn)一直是在做回文串問(wèn)題中時(shí)比較煩的地方。這個(gè)算法還有一個(gè)很好的地方就是充分利用了字符匹配的特殊性,避免了大量不必要的重復(fù)匹配。
             
               算法大致過(guò)程是這樣。先在每?jī)蓚€(gè)相鄰字符中間插入一個(gè)分隔符,當(dāng)然這個(gè)分隔符要在原串中沒(méi)有出現(xiàn)過(guò)。一般可以用'#'分隔。這樣就非常巧妙的將奇數(shù)長(zhǎng)度回文串與偶數(shù)長(zhǎng)度回文串統(tǒng)一起來(lái)考慮了(見下面的一個(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)度(包括'#')。如果這里不是特別清楚,可以自己拿出紙來(lái)畫一畫,自己體會(huì)體會(huì)。當(dāng)然這里可能每個(gè)人寫法不盡相同,不過(guò)我想大致思路應(yīng)該是一樣的吧。
               好,我們繼續(xù)。現(xiàn)在的關(guān)鍵問(wèn)題就在于怎么在O(n)時(shí)間復(fù)雜度內(nèi)求出P數(shù)組了。只要把這個(gè)P數(shù)組求出來(lái),最長(zhǎng)回文子串就可以直接掃一遍得出來(lái)了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 閱讀(462) 評(píng)論(0)  編輯 收藏 引用

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


             
            Copyright © HAOSOLA Powered by: 博客園 模板提供:滬江博客
            PK10開獎(jiǎng) PK10開獎(jiǎng)
            国产精品久久久久无码av| 国产精品久久影院| 久久妇女高潮几次MBA| 久久久无码精品亚洲日韩按摩| 精品综合久久久久久97超人| 久久综合九色欧美综合狠狠| 久久er99热精品一区二区| 久久精品无码一区二区日韩AV| 久久精品国产精品亚洲精品| 国产成人无码精品久久久久免费 | 午夜久久久久久禁播电影| 久久精品成人免费网站| 久久婷婷国产剧情内射白浆| 久久99国产一区二区三区| 国产精品无码久久久久久| 久久中文字幕人妻熟av女| 狠狠精品久久久无码中文字幕| 亚洲综合伊人久久大杳蕉| 天天做夜夜做久久做狠狠| 久久精品国产影库免费看| 久久夜色精品国产噜噜亚洲AV| 欧美激情精品久久久久久久九九九 | 久久精品这里只有精99品| 九九精品99久久久香蕉| 亚洲AV无码久久精品狠狠爱浪潮| 欧美日韩精品久久久久| 国产日韩久久久精品影院首页| 国产精品禁18久久久夂久| 奇米影视7777久久精品| 久久丫精品国产亚洲av| 久久久久久国产精品无码下载| 欧美亚洲日本久久精品| 欧美伊人久久大香线蕉综合69| 韩国三级中文字幕hd久久精品| 国产99久久九九精品无码| 国产日韩久久久精品影院首页| 91精品国产高清久久久久久91| 久久99精品国产99久久6男男| 久久精品国产亚洲沈樵| 久久久久国产成人精品亚洲午夜| 欧美麻豆久久久久久中文|