Pagini recente » Cod sursa (job #2255816) | Cod sursa (job #385117) | Cod sursa (job #654058) | Cod sursa (job #966026) | Cod sursa (job #1599106)
#include<cstdio>
#include<cstring>
using namespace std;
FILE *in, *out;
const int nMax = 19, sMax = 30050;
int n;
char s[nMax][sMax], f[sMax * 2];
int z[sMax * 2], lung[nMax], cost[nMax][nMax], din[1<<nMax][nMax], pred[1<<nMax][nMax];
bool e[nMax];
int zFunction(int x, int y, int type){
for(int i = 0 ; i < lung[y] ; ++i) f[i] = s[y][i];
f[lung[y]] = '@';
for(int i = 0 ; i < lung[x] ; ++i) f[i + lung[y] + 1] = s[x][i];
int l = lung[x] + lung[y] + 1, L, R, k, co = 0, co2 = 0;
L = R = 0;
for(int i = 0 ; i < l ; ++i){
if(i > R){
L = R = i;
while(R < l && f[R] == f[R-L]) R++;
z[i] = R - L, R--;
}else{
k = i - L;
if(z[k] > R - i){
L = i;
while(R < l && f[R] == f[R-L]) R++;
z[i] = R - L, R--;
}else{
z[i] = z[k];
}
}
if(i > lung[y] && z[i] == l - i && z[i] > co) co = z[i];
if(i > lung[y] && z[i] >= lung[y]) co2 = 1;
}
if(type) return co;
return co2;
}
void recSir(int nod, int mask){
int newNod = pred[mask][nod], inc = 0;
if(newNod > -1){
recSir(newNod, mask ^ (1 << nod));
inc = cost[newNod][nod];
}
fputs(s[nod] + inc, out);
}
int main(){
in = fopen("adn.in","r");
out = fopen("adn.out","w");
fscanf(in,"%d\n", &n);
for(int i = 0 ; i < n ; ++i){
fgets(s[i], sMax, in);
lung[i] = strlen(s[i]) - 1;
}
for(int i = 0 ; i < n ; ++i){
for(int j = 0 ; j < n ; ++j){
if(i != j && lung[i] <= lung[j] && !e[i] && !e[j]){
if(zFunction(j, i, 0))
e[i] = true;
}
}
}
int cnt = 0;
for(int i = 0; i < n ; ++i){
if(!e[i]){
for(int k = 0 ; k < lung[i] ; ++k)
s[cnt][k] = s[i][k];
s[cnt][lung[i]] = 0;
lung[cnt] = lung[i];
++cnt;
}
}
n = cnt;
for(int i = 0 ; i < n ; ++i)
for(int j = 0 ; j < n ; ++j)
if(i != j)
cost[i][j] = zFunction(i, j, 1);
for(int i = 1 ; i < 1 << n ; ++i)
for(int j = 0 ; j < n ; ++j){
pred[i][j] = -1;
if(i &(1 << j))
for(int k = 0 ; k < n ; ++k)
if(j != k && i & (1 << k))
if(din[i][j] <= din[i ^ (1 << j)][k] + cost[k][j]){
din[i][j] = din[i ^ (1 << j)][k] + cost[k][j];
pred[i][j] = k;
}
}
int co = 0, nodC = 0;
for(int i = 0 ; i < n ; ++i){
if(din[(1 << n) - 1][i] >= co){
co = din[(1 << n) - 1][i];
nodC = i;
}
}
recSir(nodC, (1 << n) - 1);
fprintf(out,"\n");
return 0;
}