Pagini recente » Cod sursa (job #1388002) | Istoria paginii runda/preoji2020 | Cod sursa (job #1243299) | Cod sursa (job #2004812) | Cod sursa (job #384667)
Cod sursa(job #384667)
#include <cstdio>
#include <cstring>
#define MAX_N 18
#define MAX_L 30001
#define INF 0x3f3f3f3f
int N, Sz[MAX_N], M;
char S[MAX_N][MAX_L];
int C[MAX_N][MAX_N], pi[MAX_N];
int A[1 << MAX_N][MAX_N], T[MAX_N];
struct adn
{
int x, y;
} Ant[1 << MAX_N][MAX_N];
void citire()
{
scanf("%d",&N);
for(int i = 0; i < N; ++i)
{
scanf(" %s",S[i]+1);
Sz[i] = strlen(S[i]+1);
}
}
void make_prefix(char A[MAX_N], int N)
{
pi[1] = 0;
for(int i = 2, q = 0; i <= N; ++i)
{
while(q && A[q+1] != A[i])
q = pi[q];
if(A[q+1] == A[i])
pi[i] = q;
}
}
int search(char A[MAX_N], int N, char B[MAX_N], int M)
{
make_prefix(A, N);
for(int i = 1, q = 0; i <= M; ++i)
{
while(q && A[q+1] != B[i])
q = pi[q];
if(A[q+1] == B[i])
++q;
if(i == M)
return q;
if(q == N)
return -1;
}
return 0;
}
void pre()
{
for(int i = 0; i < N; ++i)
for(int j = i; j < N; ++j)
{
C[i][j] = search(S[j], Sz[j], S[i], Sz[i]);
C[j][i] = search(S[i], Sz[i], S[j], Sz[j]);
}
}
void solve()
{
M = 1 << N;
for(int i = 0; i < M; ++i)
for(int j = 0; j < N; ++j)
A[i][j] = INF;
for(int i = 0; i < N; ++i)
A[(1 << i)][i] = Sz[i];
for(int i = 1; i < M; ++i)
for(int j = 0; j < N; ++j)
{
if(A[i][j] == INF) continue;
for(int k = 0; k < N; ++k)
{
if(i & (1 << k)) continue;
if(j == k) continue;
int _i = i + (1 << k);
if(C[j][k] == -1)
{
if(A[_i][j] > A[i][j])
{
A[_i][j] = A[i][j];
Ant[_i][j].x = i;
Ant[_i][j].y = j;
}
}
else
if(A[_i][k] > A[i][j] + Sz[k] - C[j][k])
{
A[_i][k] = A[i][j] + Sz[k] - C[j][k];
Ant[_i][k].x = i;
Ant[_i][k].y = j;
}
}
}
}
void reconst()
{
int x = M-1, y = 0, Sol = A[M-1][0], nr = N;
for(int i = 1; i < N; ++i)
if(Sol > A[M-1][i])
Sol = A[M-1][i],
y = i;
while(x)
{
T[--nr] = y;
int auxx = Ant[x][y].x, auxy = Ant[x][y].y;
x = auxx;
y = auxy;
}
for(int i = 1; i <= Sz[T[0]]; ++i)
printf("%c",S[T[0]][i]);
for(int i = 1; i < N; ++i)
for(int j = C[T[i-1]][T[i]]+1; j <= Sz[T[i]]; ++j)
printf("%c", S[T[i]][j]);
}
int main()
{
freopen("adn.in","rt",stdin);
freopen("adn.out","wt",stdout);
citire();
pre();
solve();
reconst();
}