Pagini recente » Cod sursa (job #2926442) | Cod sursa (job #459521) | Cod sursa (job #236283) | Cod sursa (job #609049) | Cod sursa (job #1536366)
#include <cstdio>
#include <cstring>
#define DIM1 18
#define DIM2 32768
#define INF 10000000
using namespace std;
int K, N, MIN, POS, len, Q;
int D[(1<<DIM1)][DIM1], T[(1<<DIM1)][DIM1], C[DIM1][DIM1];
char String[DIM1][DIM2], c; int S[DIM1], Seen[DIM1], V[DIM1];
int getSuffix (char String1[], char String2[]) {
int Prefix[DIM2], N, M, K; Prefix[0] = -1;
N = strlen (String1);
M = strlen (String2);
K = -1;
for (int i = 1; i < N; i ++) {
while (K != -1 && String1[K+1] != String1[i])
K = Prefix[K];
if (String1[K+1] == String1[i])
K += 1;
Prefix[i] = K;
}
K = -1;
for (int i = 1; i < M; i ++) {
while (K != -1 && String1[K+1] != String2[i])
K = Prefix[K];
if (String1[K+1] == String2[i])
K ++;
if (K == N - 1) // al 2-lea sir e inclus complet in primul deci nu il mai numar
return 0;
}
return N-K-1; // nu e inclus deci ii iau doar finalul (N-K-1)
}
void DFS (int val, int pos) {
if (val == 0)
return;
else {
S[++K] = V[pos];
DFS (val - (1<<pos), T[val][pos]);
}
return;
}
int main () {
freopen ("adn.in" ,"r", stdin );
freopen ("adn.out","w", stdout);
scanf ("%d", &N);
scanf ("%c", &c);
for (int i = 0; i < N; i ++)
scanf ("%s", String[i]);
for (int i = 0; i < N; i ++)
for (int j = 0; j < N; j ++) {
if (i != j) {
C[i][j] = getSuffix (String[j], String[i]);
if (!C[i][j]) Seen[j] = 1; /* INSPIRED */
}
}
for (int i = 0; i < (1<<N); i ++)
for (int j = 0; j < N; j ++)
D[i][j] = INF;
/* INSPIRED */
for (int i = 0; i < N; i ++) {
if (Seen[i])
continue;
V[Q] = i;
D[(1<<Q)][Q++] = strlen (String[i]);
}
/* INSPIRED */
for (int i = 1; i < (1<<N); i ++)
for (int j = 0; j < N; j ++) {
if (!(i & (1<<j)))
continue;
for (int k = 0; k < N; k ++) {
if (!(!((i>>k)&1)))
continue;
if (D[i+(1<<k)][k] > D[i][j] + C[V[j]][V[k]]) {
D[i+(1<<k)][k] = D[i][j] + C[V[j]][V[k]];
T[i+(1<<k)][k] = j;
}
}
}
MIN = INF;
for (int i = 0; i < N; i ++) {
if (D[(1<<N)-1][i] < MIN) {
MIN = D[(1<<N)-1][i];
POS = i;
}
}
DFS ((1<<N)-1, POS);
len = strlen (String[S[K]]);
for (int i = 0; i < len; i ++)
printf ("%c", String[S[K]][i]);
K --;
while (K) {
len = strlen (String[S[K]]);
for (int i = len - C[S[K+1]][S[K]]; i < len; i ++)
printf ("%c", String[S[K]][i]);
K --;
}
return 0;
}