Pagini recente » Cod sursa (job #1994410) | Cod sursa (job #1998560) | Cod sursa (job #104877) | Cod sursa (job #483799) | Cod sursa (job #2587051)
#include <iostream>
#include <cstdio>
#include <cstring>
#define NMAX 18
#define LMAX 30000
using namespace std;
int n, p18 = 1 << 18;
int l[NMAX];
int urm[LMAX + 5];
int d[1 << NMAX][NMAX][2]; /// tin minte si de unde am venit
char s[NMAX][LMAX + 5];
char p[2 * LMAX + 5];
int prefix(char *pattern, int lp, int l1) {
int k, bestk = 0;
urm[0] = 0;
for(int i = 1; i < lp; i++) {
k = urm[i - 1];
while(k > 0 && pattern[i] != pattern[k])
k = urm[k - 1];
if(pattern[i] == pattern[k])
k++;
urm[i] = k;
bestk = max(bestk, k);
}
return bestk;
}
void get_adn(int ind, int bm) {
if(d[bm][ind][1] == -1)
printf("%s", s[ind]);
else {
int old_bm = bm ^ (1 << ind), dad = d[bm][ind][1], old_l = d[old_bm][dad][0], crt_l = d[bm][ind][0];
get_adn(dad, old_bm);
printf("%s", s[ind] + l[ind] - crt_l + old_l);
}
}
bool inside(int ind1, int ind2) {
int aux = prefix(s[ind2], l[ind2], l[ind2]), k = 0;
for(int i = 0; i < l[ind1]; i++) {
while(k > 0 && s[ind1][i] != s[ind2][k])
k = urm[k - 1];
if(s[ind1][i] == s[ind2][k])
k++;
if(k == l[ind2])
return true;
}
return false;
}
void elim(int ind) {
for(int i = ind; i < n; i++)
swap(s[i], s[i + 1]), swap(l[i], l[i + 1]);
n--;
}
int main() {
freopen("adn.in", "r", stdin);
freopen("adn.out", "w", stdout);
int pn;
scanf("%d ", &n);
for(int i = 0; i < n; i++) {
scanf("%s", &s[i]);
l[i] = strlen(s[i]);
}
for(int i = 0; i < n; i++)
for(int j = 0; j < n; j++)
if(j != i && inside(i, j)) /// daca j se afla in interiorul lui i
elim(j--);
pn = 1 << n;
for(int bm = 1; bm < pn; bm++)
for(int i = 0; i < n; i++)
if(bm & (1 << i)) {
int nbm = bm ^ (1 << i);
if(nbm == 0)
d[bm][i][0] = l[i], d[bm][i][1] = -1;
else {
strncpy(p, s[i], l[i]);
for(int j = 0; j < n; j++)
if(nbm & (1 << j)) {
strncpy(p + l[i], s[j], l[j]);
int ll = prefix(p, l[i] + l[j], l[i]);
if(d[bm][i][0] == 0 || d[nbm][j][0] - ll + l[i] < d[bm][i][0]) {
d[bm][i][0] = d[nbm][j][0] - ll + l[i];
d[bm][i][1] = j;
}
}
}
}
int minim = 18 * LMAX + 5, pozmin;
for(int i = 0; i < n; i++)
if(d[pn - 1][i][0] != 0 && d[pn - 1][i][0] < minim)
minim = d[pn - 1][i][0], pozmin = i;
get_adn(pozmin, pn - 1);
return 0;
}