Pagini recente » Cod sursa (job #820859) | Cod sursa (job #2209489) | Cod sursa (job #1812691) | Cod sursa (job #364718) | Cod sursa (job #34686)
Cod sursa(job #34686)
# include <stdio.h>
# include <string.h>
# define _fin "adn.in"
# define _fout "adn.out"
# define maxn 20
# define maxw 30003
# define pow2n 262244
int c[maxn][maxn], out[maxn], n;
char w[maxn][maxw];
int a[maxn][pow2n], f[maxn][pow2n];
int sol[maxn];
void readf()
{
freopen(_fin, "r", stdin);
scanf("%d\n", &n);
for (int i=1; i<=n; i++)
scanf("%s\n", w[i]),
memmove(w[i]+1, w[i], sizeof(w[i])), w[i][0]='0';
}
int p[maxw];
int kmp(int a, int b, int &match)
{
int k=0, i, to=strlen(w[b]);
memset(p, 0, sizeof(p));
for (i=2; i<to; i++)
{
while ( k>0 && w[b][k+1] != w[b][i] ) k=p[k];
k += ( w[b][k+1]==w[b][i] );
p[i]=k;
}
for (i=1, to=strlen(w[a]); i<to; i++)
{
while ( k>0 && w[b][k+1] != w[a][i] ) k=p[k];
k += ( w[b][k+1]==w[a][i] );
if ( k==strlen(w[b])-1 ) {
match=strlen(w[b])-1;
return 1;
}
}
match=k;
return 0;
}
void presolve()
{
// precalculate N and C
int i, j, foo;
// first, take out all words that we don't need
for (i=1; i<=n; i++)
for (j=1; j<=n; j++)
{
if ( i==j ) continue;
if ( kmp(i, j, foo) )
out[j]=1;
}
for (i=n; i>=1; i--)
if ( out[i] )
memcpy(w[i], w[n], sizeof(w[n])), n--;
for (i=1; i<=n; i++)
for (j=1; j<=n; j++)
{
if ( i==j ) continue;
kmp(i, j, c[i][j]);
}
}
void solve()
{
int i, j, k, l, to=(1<<n)-1;
memset(a, 0xff, sizeof(a));
for (i=1; i<=n; i++) a[i][1<<(i-1)]=0;
for (i=3; i<=to; i++)
for (j=1; j<=n; j++) {
if ( !(i & (1<<(j-1))) ) continue;
for (k=1; k<=n; k++)
if ( i & (1<<(k-1)) )
if ( c[j][k] + a[k][ i ^ (1<<(j-1)) ] > a[j][i] )
a[j][i] = c[j][k] + a[k][i^(1<<(j-1))], f[j][i]=k;
}
int max=1;
for (i=2; i<=n; i++)
if ( a[i][to] > a[max][to] ) max=i;
for (i=max, j=to; f[i][j]; k=i, i=f[i][j], j^=(1<<(k-1)))
sol[ ++sol[0] ] = i;
sol[ ++sol[0] ] = i;
}
void writef()
{
freopen(_fout, "w", stdout);
int i;
for (printf("%s", w[sol[1]]+1), i=2; i<=sol[0]; i++)
printf("%s", w[sol[i]] + c[sol[i-1]][sol[i]]+1);
printf("\n");
}
int main()
{
readf();
presolve();
solve();
writef();
return 0;
}