Pagini recente » Cod sursa (job #2019236) | Cod sursa (job #3188943) | Cod sursa (job #2442548) | Cod sursa (job #2457364) | Cod sursa (job #1482732)
#include <stdio.h>
#define MAXN 18
#define MAXL 30000
#define INF 1000000000
char s[MAXN][MAXL + 2];
int l[MAXN], cost[MAXN][MAXN];
int d[MAXN][(1 << MAXN) - 1];
char ot[MAXL * MAXN + 1];
int dr = 0;
int pi[MAXL];
char bun[MAXN];
inline int max2(int a, int b){
return a > b ? a : b;
}
inline char inc(int a, int b){
int k = -1, i;
for(i = 0; i < l[b]; i++){
while(k != -1 && s[a][k + 1] != s[b][i])
k = pi[k];
if(s[a][k + 1] == s[b][i])
k++;
if(k == l[a] - 1)
return 1;
}
return 0;
}
inline void calcpi(int a){
int k = -1, i;
pi[0] = -1;
for(i = 1; i < l[a]; i++){
while(k != -1 && s[a][i] != s[a][k + 1])
k = pi[k];
if(s[a][i] == s[a][k + 1])
k++;
pi[i] = k;
}
}
inline void copy(int a, int b){
int i;
for(i = 0; i < l[b]; i++)
s[a][i] = s[b][i];
l[a] = l[b];
}
inline void verif(int *n){
int i, j;
for(i = 0; i < *n; i++)
bun[i] = 1;
for(i = 0; i < *n; i++){
if(bun[i]){
calcpi(i);
for(j = 0; j < *n; j++){
if(i != j && bun[j] && l[i] <= l[j]){
if(inc(i, j))
bun[i] = 0;
}
}
}
}
j = 0;
for(i = 0; i < *n; i++){
if(bun[i]){
copy(j, i);
j++;
}
}
*n = j;
}
inline void calccost(int n){
int i, j, k, t;
for(i = 0; i < n; i++){
calcpi(i);
for(j = 0; j < n; j++){
if(i != j){
k = -1;
for(t = 0; t < l[j]; t++){
while(k != -1 && s[i][k + 1] != s[j][t])
k = pi[k];
if(s[i][k + 1] == s[j][t])
k++;
}
cost[i][j] = k + 1;
}
}
}
}
int solve(int bin, int x, int n){
int i;
if(d[x][bin] == -INF)
for(i = 0; i < n; i++)
if(bin & (1 << i))
d[x][bin] = max2(d[x][bin], solve(bin - (1 << i), i, n) + cost[x][i]);
return d[x][bin];
}
void recon(int bin, int x, int n){
int i, j;
if(bin == 0){
for(i = 0; i < l[x]; i++){
ot[dr] = s[x][i];
dr++;
}
}
else{
for(i = 0; i < n; i++){
if((bin & (1 << i)) && d[x][bin] == d[i][bin - (1 << i)] + cost[x][i]){
recon(bin - (1 << i), i, n);
for(j = cost[x][i]; j < l[x]; j++){
ot[dr] = s[x][j];
dr++;
}
i = n;
}
}
}
}
int main(){
FILE *in = fopen("adn.in", "r");
int n, i;
fscanf(in, "%d ", &n);
for(i = 0; i < n; i++){
fgets(s[i], MAXL + 2, in);
l[i] = 0;
while(s[i][l[i]] != '\n')
l[i]++;
}
fclose(in);
verif(&n);
calccost(n);
int rez = -INF, p = -1, x, j;
for(i = 0; i < n; i++)
for(j = 0; j < (1 << n); j++)
d[i][j] = -INF;
for(j = 0; j < n; j++)
d[j][0] = 0;
for(i = 0; i < n; i++){
x = solve((1 << n) - 1 - (1 << i), i, n);
if(x > rez){
rez = x;
p = i;
}
}
recon((1 << n) - 1 - (1 << p), p, n);
FILE *out = fopen("adn.out", "w");
fputs(ot, out);
fclose(out);
return 0;
}