Pagini recente » Cod sursa (job #2829931) | Cod sursa (job #1489529) | Cod sursa (job #373469) | Cod sursa (job #566792) | Cod sursa (job #2216159)
#include <bits/stdc++.h>
using namespace std;
int n;
char s[19][31005];
int c[19], cost[19][19];
int pi[19][31005];
int d[272144][19];
int TT[272144][19];
vector <int> Sol;
inline void ma(char s[], int pi[]){
pi[1] = 0;
int n = strlen(s + 1);
for(int i = 2; i <= n ; ++i){
int q = pi[i - 1];
while(q && s[q + 1] != s[i])
q = pi[q];
if(s[q + 1] == s[i]) ++q;
pi[i] = q;
}
}
inline int gi(char a[], char b[], int pi[]){
int q = 0;
int n = strlen(b + 1);
for(int i = 1; i <= n ; ++i){
while(a[q + 1] != b[i] && q)
q = pi[q];
if(a[q + 1] == b[i]) ++q;
}
return q;
}
inline bool pc(char a[], char b[], int pi[]){
int q = 0;
int n = strlen(b + 1), m = strlen(a + 1);
for(int i = 1; i <= n ; ++i){
while(a[q + 1] != b[i] && q)
q = pi[q];
if(a[q + 1] == b[i]) ++q;
if(q == m) return 1;
}
return 0;
}
int main()
{
freopen("adn.in", "r", stdin);
freopen("adn.out", "w", stdout);
scanf("%d", &n);
for(int i = 0; i < n ; ++i){
scanf("%s", s[i] + 1);
ma(s[i], pi[i]);
c[i] = strlen(s[i] + 1);
}
for(int i = 0; i < n ; ++i){
for(int j = 0; j < n ; ++j){
if(i == j || c[j] < c[i]) continue ;
bool ok = pc(s[i], s[j], pi[i]);
if(ok){
for(int j = i; j < n - 1 ; ++j){
strcpy(s[j] + 1, s[j + 1] + 1);
c[j] = c[j + 1];
memcpy(pi[j], pi[j + 1], sizeof(pi[j + 1]));
}
--n; --i;
break ;
}
}
}
for(int i = 0; i < n ; ++i){
for(int j = 0; j < n ; ++j){
if(i == j) continue ;
int l = gi(s[j], s[i], pi[j]);
cost[i][j] = -l;
}
}
memset(d, 0x3f, sizeof(d));
for(int i = 0; i < n ; ++i)
d[(1 << i)][i] = c[i];
for(int mask = 0; mask < (1 << n) ; ++mask){
for(int i = 0; i < n ; ++i){
if(!((1 << i) & mask)) continue ;
for(int j = 0; j < n ; ++j){
if((1 << j) & mask) continue ;
int mask2 = (1 << j) | mask;
int C = d[mask][i] + cost[i][j] + c[j];
if(C < d[mask2][j]){
d[mask2][j] = C;
TT[mask2][j] = i;
}
}
}
}
int Min = 2000000000, w = 0, mask = (1 << n) - 1;
for(int i = 0; i < n ; ++i)
if(d[mask][i] < Min) Min = d[mask][i], w = i;
while(mask){
Sol.push_back(w);
int aux = mask; mask = mask - (1 << w);
w = TT[aux][w];
}
reverse(Sol.begin(), Sol.end());
printf("%s", s[Sol[0]] + 1);
int Last = -cost[Sol[0]][Sol[1]];
for(int i = 1; i < Sol.size() ; ++i){
printf("%s", s[Sol[i]] + Last + 1);
if(i + 1 < Sol.size()) Last = -cost[Sol[i]][Sol[i + 1]];
}
return 0;
}