Pagini recente » Cod sursa (job #2322742) | Cod sursa (job #2592817) | Cod sursa (job #2794752) | Cod sursa (job #1668702) | Cod sursa (job #79792)
Cod sursa(job #79792)
#include <stdio.h>
#include <string.h>
#define MAX( a, b ) ( (a) > (b) ) ? a : b
#define MIN( a, b ) ( (a) < (b) ) ? a : b
#define FIN "adn.in"
#define FOUT "adn.out"
#define NMAX 19
#define LEN 30005
char A[NMAX][LEN];
char S[ 2 * LEN];
int PI[ 2 * LEN ], C[NMAX][NMAX];
int OUT[NMAX], P[NMAX];
int COST[NMAX][1<<NMAX];
int N, i, j, start;
FILE * fin, * fout;
void build_pi( char S[], int PI[] )
{
int i, k = -1;
PI[0] = -1;
for( i = 1; i < strlen(S); i++ )
{
while ( ( k > -1 ) && ( S[i] != S[k+1] )) k = PI[k];
if (S[i] == S[k+1]) k++;
PI[i] = k;
}
}
int KMP( char T[], char S[] )
{
int k = -1, i;
memset( PI, 0, sizeof( PI ));
build_pi( S, PI );
for( i = 0; i < strlen(T); i++)
{
while ( ( k > -1 ) && ( T[i] != S[k+1] ) ) k = PI[k];
if ( T[i] == S[k+1] ) k++;
if ( k == strlen(S) - 1 ) return 1;
}
return 0;
}
void elimin()
{
int i, j;
memset( OUT, 0, sizeof(OUT) );
for( i = 1; i <= N; i++ )
for( j = 1; j <= N; j++ )
if ( (!OUT[j]) && ( i != j ) )
if ( KMP( A[j], A[i] ) )
{
OUT[i] = 1;
break;
}
int n = 0;
for( i = 1; i <= N; i++ )
if (!OUT[i])
{
n++; P[n] = i; // memorez indicii sirurilor ramase
}
N = n;
}
void build_cost()
{
int i, j;
memset( C, 0, sizeof( C ) );
for( i = 1; i <= N; i++ )
for( j = 1; j <= N; j++)
if ( i != j )
{
strcpy( S, A[P[j]] );
strcat( S, "#" );
strcat( S, A[P[i]] );
build_pi( S, PI );
C[i][j] = PI[ strlen(A[P[i]]) + strlen( A[P[j]] ) ] + 1;
}
}
void dinamica()
{
int i, j, k;
for( j = 1; j <= (1 << N) - 1; j++)
for( i = 0; i < N; i++)
if ( (( 1 << i ) & j) > 0 )
for( k = 0; k < N; k++)
if ( k != i )
if ( (( 1 << k ) & j) > 0 )
if ( COST[i+1][j] < COST[k+1][j - ( 1 << i )] + C[k+1][i+1] )
COST[i+1][j] = COST[k+1][ j - ( 1 << i )] + C[k+1][i+1];
}
void reconst( int start )
{
int p = 1, all = (1 << N ) - 1;
int i;
memset( OUT, 0, sizeof( OUT ) );
OUT[p] = start;
while ( p < N )
{
for( i = 0; i < N; i++ )
{
if ( i+1 != start )
if (( ( 1 << i ) & all ) > 0 )
if ( COST[start][all] == COST[i+1][all - ( 1 << ( start-1))] + C[i+1][start])
{
all -= 1 << ( start - 1 );
p++; OUT[p] = i+1;
start = i+1;
break;
}
}
}
}
int main()
{
fin = fopen( FIN, "r" );
fout = fopen( FOUT, "w" );
fscanf( fin, "%d\n", &N );
for( i = 1; i <= N; i++ )
{
fgets( A[i], LEN, fin );
A[i][ strlen(A[i]) - 1] = 0;
}
elimin();
build_cost();
dinamica();
int max = 0;
for( i = 1; i <= N; i++)
if ( COST[i][(1<<N)-1] > max )
{
max = COST[i][(1<<N)-1];
start = i;
}
reconst( start );
fputs( A[P[OUT[N]]], fout );
for( i = N - 1; i > 0; i--)
{
for( j = C[OUT[i+1]][OUT[i]]; j < strlen( A[P[OUT[i]]] ); j++ )
fprintf( fout, "%c", A[P[OUT[i]]][j] );
}
fprintf( fout, "\n");
fclose( fin );
fclose( fout );
return 0;
}