Pagini recente » Cod sursa (job #948650) | Cod sursa (job #2968936) | Cod sursa (job #825207) | Cod sursa (job #239140) | Cod sursa (job #683404)
Cod sursa(job #683404)
#include<stdio.h>
#include<cstring>
#include<cstdlib>
#define maxn 20
#define maxdim 30005
FILE*f=fopen("adn.in","r");
FILE*g=fopen("adn.out","w");
const int INF = (1<<29);
int n,last;
int pi[maxdim],D[maxn][maxn],Len[maxn],Best[maxn-1][1<<(maxn-2)],T[maxn-1][1<<(maxn-2)];
char A[maxn][maxdim];
inline void citire () {
fscanf(f,"%d",&n);
for ( int i = 1 ; i <= n ; ++i ){
fscanf(f,"%s",A[i]+1);
Len[i] = strlen(A[i]+1);
}
}
inline void prefix ( char *A , int n ){
int k = 0;
for ( int i = 2 ; i <= n ; ++i ){
while ( k > 0 && A[k+1] != A[i] ){
k = pi[k];
}
if ( A[k+1] == A[i] ){
k = k + 1;
}
pi[i] = k;
}
}
inline int kmp ( char *A , int n , char *B , int m ){
int q = 0;
for ( int i = 1 ; i <= m ; ++i ){
while ( q > 0 && A[q+1] != B[i] ){
q = pi[q];
}
if ( A[q+1] == B[i] ){
q = q + 1;
}
if ( q == n ){
return -1;
}
}
return q;
}
inline void calculeaza () {
for ( int i = 1 ; i <= n ; ++i ){
prefix(A[i],Len[i]);
for ( int j = 1 ; j <= n ; ++j ){
if ( i != j ){
if ( kmp(A[i],Len[i],A[j],Len[j]) == -1 ){
memcpy(A[i],A[n],sizeof(A[n])); Len[i] = Len[n];
memset(A[n],0,sizeof(0));
--n; --i;
break ;
}
}
}
}
if ( n == 1 ){
fprintf(g,"%s\n",A[1]+1);
fclose(f); fclose(g);
exit(0);
}
for ( int i = 1 ; i <= n ; ++i ){
D[0][i] = Len[i];
prefix(A[i],Len[i]);
for ( int j = 1 ; j <= n ; ++j ){
if ( i != j ){
D[j][i] = kmp(A[i],Len[i],A[j],Len[j]);
}
}
}
for ( int i = 1 ; i <= n ; ++i ){
for ( int j = 1 ; j <= n ; ++j ){
if ( i != j ){
D[i][j] = Len[j] - D[i][j];
}
}
}
}
inline void solve () {
for ( int i = 1 ; i < (1<<n) ; ++i ){
for ( int j = 1 ; j <= n ; ++j ){
Best[j][i] = INF;
T[j][i] = -1;
}
}
for ( int i = 1 ; i <= n ; ++i ){
Best[i][1<<(i-1)] = D[0][i];
}
for ( int i = 1 ; i < (1<<n) ; ++i ){
for ( int j = 1 ; j <= n ; ++j ){
if ( Best[j][i] != INF ) continue ;
int b1 = j - 1;
if ( i & (1<<b1) ){
for ( int k = 1 ; k <= n ; ++k ){
int b2 = k - 1;
if ( b1 != b2 && (i & (1<<b2)) ){
if ( Best[k][i^(1<<b1)] + D[k][j] < Best[j][i] ){
Best[j][i] = Best[k][i^(1<<b1)] + D[k][j];
T[j][i] = b2;
}
}
}
}
}
}
last = 1;
for ( int i = 2 ; i <= n ; ++i ){
if ( Best[i][(1<<n)-1] < Best[last][(1<<n)-1] ){
last = i;
}
}
}
void print ( int conf , int bit ){
if ( !conf ){
return ;
}
int nr = D[T[bit+1][conf]+1][bit+1];
print(conf^(1<<bit),T[bit+1][conf]);
int cuv = bit + 1;
fprintf(g,"%s",A[cuv]+Len[cuv]-nr+1);
if ( conf == (1<<n)-1 )
fprintf(g,"\n");
}
int main () {
citire();
calculeaza();
solve();
print((1<<n)-1,last-1);
fclose(f);
fclose(g);
return 0;
}