Pagini recente » Cod sursa (job #1453714) | Cod sursa (job #2046160) | Cod sursa (job #1964846) | Cod sursa (job #2557503) | Cod sursa (job #1490967)
#include<fstream>
#include<string>
#include<cstring>
using namespace std;
ifstream fin( "adn.in" ); ofstream fout( "adn.out" );
const int lgmax = 30001;
const int inf = 1 << 30;
const int nmax = 18;
int n;
int pi[ lgmax + 1 ];
int c[ nmax + 1 ][ nmax + 1 ];
int d[ (1 << nmax) ][ nmax + 1 ], p[ (1 << nmax) + 1 ][ nmax + 1 ];
char r[ (1 << nmax) ][ nmax + 1 ];
string s[ nmax + 1 ];
inline int adauga( int i, int x, int j ) {
return (d[ i - (1 << (j - 1)) ][ x ] + ( int )s[ j ].size() - 1 - c[ x ][ j ]);
}
void kmp( int x, int y ) {
memset( pi, 0, sizeof( pi ) );
pi[ 1 ] = 0;
for( int i = 2; i < ( int )s[ x ].size(); ++ i ) {
int r = pi[ i - 1 ];
while ( r != 0 && s[ x ][ r + 1 ] != s[ x ][ i ] ) {
r = pi[ r ];
}
if ( s[ x ][ r + 1 ] == s[ x ][ i ] ) {
pi[ i ] = r + 1;
} else {
pi[ i ] = 0;
}
}
int r = 0;
for( int i = 1; i < ( int )s[ y ].size(); ++ i ) {
while ( r != 0 && s[ x ][ r + 1 ] != s[ y ][ i ] ) {
r = pi[ r ];
}
if ( s[ x ][ r + 1 ] == s[ y ][ i ] ) {
++ r;
}
if ( r == ( int )s[ x ].size() - 1 ) {
c[ y ][ x ] = r; return ;
}
}
c[ y ][ x ] = r;
}
void precalc() {
for( int i = 1; i <= n; ++ i ) {
for( int j = 1; j <= n; ++ j ) {
kmp( i, j );
}
}
}
void reconst( int st, int last ) {
if ( st == 0 ) {
return ;
}
reconst( st - (1 << (last - 1)), r[ st ][ last ] );
for( int i = p[ st ][ last ]; i < ( int )s[ last ].size(); ++ i ) {
fout << s[ last ][ i ];
}
}
int main() {
fin >> n;
for( int i = 1; i <= n; ++ i ) {
fin >> s[ i ];
s[ i ] = "#" + s[ i ];
}
precalc();
d[ 0 ][ 0 ] = 0;
for( int i = 1; i < (1 << n); ++ i ) {
for( int j = 1; j <= n; ++ j ) {
d[ i ][ j ] = inf;
if ( i & (1 << (j - 1)) ) {
if ( i == (1 << (j - 1)) ) {
d[ i ][ j ] = ( int )s[ j ].size() - 1;
p[ i ][ j ] = 1;
}
bool ok = 0;
for( int x = 1; x <= n; ++ x ) {
if ( i & (1 << (x - 1)) && x != j ) {
if ( c[ x ][ j ] == ( int )s[ j ].size() - 1 ) {
ok = 1;
}
if ( d[ i ][ j ] > adauga( i, x, j ) ) {
r[ i ][ j ] = x;
d[ i ][ j ] = adauga( i, x, j );
p[ i ][ j ] = ( int )s[ j ].size() - c[ x ][ j ];
}
}
}
if ( ok == 1 ) {
d[ i ][ j ] = inf;
for( int x = 1; x <= n; ++ x ) {
if ( i & (1 << (x - 1)) && x != j ) {
if ( d[ i ][ j ] > d[ i - (1 << (j - 1)) ][ x ] ) {
d[ i ][ j ] = d[ i - (1 << (j - 1)) ][ x ];
r[ i ][ j ] = x;
p[ i ][ j ] = ( int )s[ j ].size();
}
}
}
}
}
}
}
int last = 0;
d[ (1 << n) - 1 ][ 0 ] = inf;
for( int i = 1; i <= n; ++ i ) {
if ( d[ (1 << n) - 1 ][ last ] > d[ (1 << n) - 1 ][ i ] ) {
last = i;
}
}
reconst( (1 << n) - 1, last );
fin.close();
fout.close();
return 0;
}