Pagini recente » Cod sursa (job #2989573) | Cod sursa (job #2772604) | Cod sursa (job #49449) | Cod sursa (job #476586) | Cod sursa (job #1067607)
#include <cstdio>
#include <iostream>
#include <string.h>
using namespace std;
int N;
char adn[19][30007];
int F[19][30007];
int M[19];
void build_failure() {
for (int k = 0; k < N; ++k) {
char* pat = adn[k];
F[k][0] = F[k][1] = 0;
for (int i = 2; i <= M[k]; ++i) {
F[k][i] = 0;
int j = F[k][i-1];
while (j) {
if (pat[j] == pat[i-1]) {
F[k][i] = j + 1; break;
}
j = F[k][j];
}
}
}
}
int hash_kmp[20][20];
int kmp(int k1, int k2) {
if (hash_kmp[k1][k2]) return hash_kmp[k1][k2] - 1;
// k1 ... k2
int& best = hash_kmp[k1][k2];
int i = 0, j = 0;
char* text = adn[k1];
char* pat = adn[k2];
while (1) {
if (i == M[k1]) break;
if (text[i] == pat[j]) {
++i; ++j;
if (i == M[k1] || j == M[k2]) { best = j + 1; return best - 1; }
} else {
if (j > 0) j = F[k2][j];
else ++i;
}
}
best = 1;
return 0;
}
int dp[1<<18][18];
int go(int mask, int p) {
if (mask + 1 == (1<<N)) return 0;
if (dp[mask][p]) return dp[mask][p];
int& ret = dp[mask][p];
ret = 30000 * N + 1;
for (int i = 0; i < N; ++i) if (!(mask&(1<<i))) {
int now = M[i] - kmp(p, i) + go(mask|(1<<i), (M[i]-kmp(p,i))?i:p);
if (now < ret) ret = now;
}
return ret;
}
int main() {
freopen("adn.in", "r", stdin);
freopen("adn.out", "w", stdout);
scanf("%d", &N);
for (int i = 0; i < N; ++i) {
scanf("%s", &adn[i]);
M[i] = strlen(adn[i]);
if (M[i] > 30000) while (1) {}
}
build_failure();
int best = 30000 * N + 1;
int last_i = 0;
for (int i = 0; i < N; ++i) {
int now = go((1<<i), i) + M[i];
if (now < best) best = now, last_i = i;
}
printf("%s", adn[last_i]);
int mask = (1<<last_i);
best -= M[last_i];
while (mask + 1 != (1<<N)) {
for (int i = 0; i < N; ++i) if (!(mask & (1<<i))) {
int now = go(mask | (1<<i), (M[i]-kmp(last_i,i))?i:last_i) + M[i] - kmp(last_i, i);
if (now == best) {
best -= M[i] - kmp(last_i, i);
printf("%s", adn[i] + kmp(last_i, i));
if (kmp(last_i, i) != M[i]) last_i = i;
mask |= (1<<i);
break;
}
}
}
printf("\n");
fclose(stdin);
fclose(stdout);
return 0;
}