Pagini recente » Cod sursa (job #296824) | Rating Rares Hanganu (RaresH) | Cod sursa (job #3255763) | Cod sursa (job #2938843) | Cod sursa (job #132371)
Cod sursa(job #132371)
#include <cstdio>
#include <string>
#include <iostream>
using namespace std;
#define NMAX 18
string S2[NMAX], S[NMAX], sol;
int N;
int Pi[NMAX][1<<15];
int A[NMAX][NMAX];
int pred[NMAX][1<<18];
int d[NMAX][1<<18];
char sir[1<<15];
void read ()
{
scanf ("%d\n", &N);
int i;
for (i = 1; i <= N; ++ i)
{
gets (sir);
S2[i] = sir;
S2[i] = " " + S2[i];
}
}
void Prefix (int p, int len)
{
int k = 0, i;
for (i = 2; i <= len; ++ i)
{
while (k > 0 && S2[p][k + 1] != S2[p][i])
k = Pi[p][k];
if (S2[p][k + 1] == S2[p][i])
++ k;
Pi[p][i] = k;
}
}
int KMP (int p1, int p2, int len)
{
int q = 0, maxim = 0, i;
for (i = 1; i <= len; ++ i)
{
while (q > 0 && S2[p1][q + 1] != S2[p2][i])
q = Pi[p1][q];
if (S2[p1][q + 1] == S2[p2][i])
++ q;
if (q == S2[p1].length()-1)
return -1;
}
return maxim = q;
}
int Get_Cost (int i, int mask)
{
//cout << i << " " << mask << endl;
if (d[i][mask])
return d[i][mask];
int step;
for (step = 1; step < mask; step <<= 1);
if (step == mask)
return 0;
int j, tmp, maxim = -1, p = 0;
for (j = 1; j <= N; ++ j)
if (mask & (1 << (j-1)) && j != i)
{
tmp = Get_Cost (j, mask - (1 << (i-1))) + A[j][i];
if (maxim < tmp)
{
maxim = tmp;
p = j;
}
}
pred[i][mask] = p;
return d[i][mask] = maxim;
}
void Remake (int i, int mask)
{
int p = pred[i][mask];
if (!mask || !i)
return;
Remake (p, mask - (1<<(i-1)));
if (d[i][mask] == d[p][mask-(1<<(i-1))] + A[p][i] && p != 0)
sol += S[p].substr(1, S[p].length()-1-A[p][i]);
}
void solve ()
{
int i, j;
for (i = 1; i <= N; ++ i)
{
int l = S2[i].length()-1;
Prefix (i, l);
}
for (i = 1; i <= N; ++ i)
for (j = 1; j <= N; ++ j)
if (KMP (i, j, S2[j].length()-1) == -1 && i != j)
S2[i] = "";
int ct1 = 0, ct2;
for (i = 1; i <= N; ++ i)
{
if (S2[i] == "")
continue;
++ ct1;
ct2 = 0;
for (j = 1; j <= N; ++ j)
if (S2[j] != "")
A[++ct2][ct1] = KMP (i, j, S2[j].length()-1);
}
ct1 = 0;
for (i = 1; i <= N; ++ i)
if (S2[i] != "")
S[++ct1] = S2[i];
N = ct1;
/*for (i = 1; i <= N; ++ i)
{
printf ("\n");
for (j = 1; j <= N; ++ j)
printf ("%d ", A[i][j]);
}*/
int maxim = -1, nod, tmp;
for (i = 1; i <= N; ++ i)
{
tmp = Get_Cost (i, (1<<N) - 1);
if (tmp > maxim)
{
maxim = tmp;
nod = i;
}
}
//printf ("%d\n", maxim);
Remake (nod, (1<<N) - 1);
sol += S[nod].substr(1);
printf ("%s\n", sol.c_str());
}
int
main ()
{
freopen ("adn.in", "rt", stdin);
freopen ("adn.out", "wt", stdout);
read ();
solve ();
return 0;
}