Manacher(回文配列をミラーアップ)

I - O'My!

ジム - 101350I

注意:これはミラー列Iの難しいバージョンです。

ゴリラは最近、水の表面上の画像は、実際に自分自身の反射であることを発見しました。だから、彼らが発見するために次のことは、ミラーリングされた文字列です。

ミラーリングされた文字列は、あなたが鏡にそれを表示する場合は変わりません回文文字列です。

ミラーリングされた文字列の例としては、「MOM」、「IOI」または「HUH」です。したがって、文字列のみ{A、H、I、M、O、T、U、V、W、X、Y}文字をミラーリングし、パリンドロームであることを含まなければならないミラー。

IWIW、TFCがない間例えばIWWI、MHHMは、文字列をミラーリングされています。

回文は同じ前方を読み、後方れる文字列です。

文字列を考えるとSの長さのN、文字列から作成することができる最長のミラーリングされた部分文字列の長さ印刷してゴリラを助けるSを

サブストリングは、別の文字列に含まれる文字の(おそらく空の)文字列であるS例えば「地獄」「こんにちは」の部分文字列です。


入力

入力の最初の行は、T -テストケースの数。

各テストケースは、非空の文字列が含まSの最大長さの1000の文字列は、大文字だけ、英語の文字が含まれています。

出力

各テストケースのために、ライン単一の整数で出力-列から作ることができる最長のミラーリングされたサブストリングの長さS

入力
3 
IOIKIOOI
ROQ
WOWMAN
出力
4 
1。
3つの。
アイデア:配列はほとんど重複ランタイムエラーは見られないので、鏡文字は、A最長の回文配列を求めて分割し、幸いにもました
#include <cstdioを> 
する#include <CStringの> 
する#include <cmath> 
の#include <アルゴリズム> 
の#include <iostreamの> 
する#include <cstdioを> 
する#include < ストリング > 
の#include <CStringの> 
する#include <stdio.hに> 
する#include < 文字列の.h>
 使用して 名前空間はstdを、
const  int型 N = 1000009 ;
char型 [ 10009 ]、B [ 20009を]。
int型の P [ 20009 ];
int型 VIS [ 27];
チャー C [ 20 ] = { ' A '' H '' 私は'' M '' O '' T '' U '' V '' W '' Xを'' Y ' }。
チャー D [ 10009 ]。

int型レナ)
{ 
        B [ 0 ] = ' $ ' 
        B [ 1 ] = ' ' int型、L = 2 以下のためにint型 iは= 0 ; iは<レナ; iは++ 
        { 
            [L bは ++] = [I]。
            B [L ++] = ' ' 
        } 
        B [L] = ' \ 0 ' //     coutの<< B <<てendl;
        int型のmx = - 1 ;
        int型の半ば、I。
        int型のlen = 0 ;
        int型 iは= 1 ; iが<Lを、iが++ 
        { 
                場合(MX> I)
                { 
                    P [I] =分(P [ミッド* 2 - i]は、MX - I)。
                } 
                
                { 
                    Pの[I] = 1 
                } 
                一方(B [IP [I]] == B [iが+ P [I]])
                {
                     P [i]は ++; 
                } 
                であれば(MX <P [I] + I)
                { 
                    ミッド = I。
                    MX = P [i]は+ I。
                } 
                でlen = MAX(LEN、P [I] - 1 )。

        } 
        戻りLEN。
} 

int型のmain()
{ 
    ためint型 i = 0 ; iは< 11 I ++; 
    { 
        int型、X = C [I] - [ A 'を
        VIS [X] = 1; 
    } 
    INT N; 
    scanf関数(" %のD "、&N)
    一方、(N-- 
    { 

        scanf関数(" %sの" 、A)。
        INTレナ= STRLEN(A)。
        int型 ANS = 0 ;
        INTは L = 0 以下のためにint型 i = 0 ; I <レナ; iは++ 
        { 
            場合(VIS [i]が- [ A ' ]) 
            {
                D [L ++] =[I]。
            } 
            もし(!VIS [I] - [ A ' ] || I ==レナ- 1 
            { 

                場合(L> = 1 
                    ANS = MAX(ANS、CAL(D、L))。
                D [L] = 0 ; 
                L = 0 続け; 
            } 
        } 
        のprintf(" %d個の\ n " 、ANS)。
    } 



    戻り 0 
}

 

おすすめ

転載: www.cnblogs.com/nonames/p/11291334.html