そのイタリア:複数の入力、出力のセットおよびパリンドローム配列を最小化する文字列(端部のみに挿入することができる)ように構成
アイデア:文字列は、DP LCS(最長共通サブプロセス)の方法のいずれかを有することができるケースに挿入された場合。我々は、文字列s、S1はDPによって見出さ最長共通サブシーケンスの逆に設定されて入れ、その後元の長さを減算して完了(挿入された場合)の最長共通部分列の長さであります
しかし、この問題は、それが連続サブストリングマッチングする必要があります最後に追加されたので、私たちは、連続したサブセクションの最長の文字列に一致するようにKMPアルゴリズムを使用し、これが進行完了の同じ部分ではありません。
完全なコード:
書式#include <cstdioを> する#include <CStringの> の#include < 文字列 > の#include <iostreamの> の#include <cmath> の#include <アルゴリズム> 使用して 名前空間はstdを、 const int型 MAXN = 1000年。 int型NEX [MAXN]。 int型LEN1、LEN2。 文字列、B; ボイドGETNEXT(){ int型 I = 0、J = - 1。// 私为副串的序号 NEX [i]は= J; 一方(iは< {LEN2)の 場合(J == - 1 || B [I] == B [J]){ NEX [ ++ I] = ++ J。 } そう J = NEX [J]。 } } int型KMP(){ int型 ANS = 0 。 int型 CNT = 0 ; int型のカウント= 0 ; int型 I = 0、J = 0 ; GETNEXT(); 用(i = 0 ; I <LEN1; iは++ ) { 一方(J> 0!&& [I] = B [J]){ J =NEX [J]。 CNT = 0 ; } もし([I] == B [J]){ J ++。CNT ++ ; カウント = MAX(CNTを、カウント); } } リターン回数、 } int型のmain() { int型レナ、LENB、I、J。 一方、(CIN >> A) { b.assign(A)。 逆(b.begin()、b.end())。 LEN1 = a.size()。 LEN2 = b.size()。 int型 ANS =KMP(); もし(ANS == LEN1)COUT << << ENDL。 他{ ストリング S = b.substr(ANS、LEN1)。 coutの << << S << てendl; } } 戻り 0 。 }