Pagini recente » Cod sursa (job #1990431) | Cod sursa (job #2051468) | Cod sursa (job #1392145) | Cod sursa (job #1144852) | Cod sursa (job #132330)
Cod sursa(job #132330)
#include <cstdio>
#include <string>
#include <iostream>
using namespace std;
#define NMAX 18
string S[NMAX], sol;
int N;
int Pi[NMAX][1<<15];
int A[NMAX][NMAX];
int d[NMAX][1<<18];
int pred[NMAX][1<<18];
char sir[1<<15];
void read ()
{
scanf ("%d\n", &N);
int i;
for (i = 0; i < N; ++ i)
{
gets (sir);
S[i] = sir;
S[i] = " " + S[i];
}
}
void Prefix (int p, int len)
{
int k = 0, i;
for (i = 2; i <= len; ++ i)
{
while (k > 0 && S[p][k + 1] != S[p][i])
k = Pi[p][k];
if (S[p][k + 1] == S[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 && S[p1][q + 1] != S[p2][i])
q = Pi[p1][q];
if (S[p1][q + 1] == S[p2][i])
++ q;
if (q == S[p1].length()-1)
return -1;
}
return maxim = q;
}
int Get_Cost (int i, int mask)
{
mask -= (1 << i);
//cout << i << " " << mask << endl;
if (d[i][mask])
return d[i][mask];
if (!mask)
return 0;
int j, tmp, maxim = 0, p = 0;
for (j = 0; j < N; ++ j)
if (mask & (1 << j) && A[j][i] != -1)
{
tmp = Get_Cost (j, mask) + 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)
{
mask -= (1<<i);
if (!mask)
{
//cout << S[i] << " " << i << endl;
if (S[i] != "")
sol += S[i].substr(1, S[i].length()-1);
return;
}
int p = pred[i][mask];
//printf ("%s\n", S[i].c_str());
//cout << p << " " << i << endl;
Remake (p, mask);
sol += S[i].substr(A[p][i]+1, S[i].length()-1);
//cout << sol << endl;
}
void solve ()
{
int i, j;
for (i = 0; i < N; ++ i)
Prefix (i, S[i].length()-1);
for (i = 0; i < N; ++ i)
for (j = 0; j < N; ++ j)
if (KMP (i, j, S[j].length()-1) == -1 && i != j)
S[i] = "";
for (i = 0; i < N; ++ i)
for (j = 0; j < N; ++ j)
if (S[j] != "" && S[i] != "" && i != j)
A[j][i] = KMP (i, j, S[j].length()-1);
else
A[j][i] = 0;
/*//cout << S[1] << endl << S[4]<< endl;
//printf ("%d\n", KMP(4, 1, S[1].length()-1));
for (i = 0; i < N; ++ i)
{
printf ("\n");
for (j = 0; j < N; ++ j)
printf ("%d ", A[i][j]);
}*/
int maxim = 0, nod, tmp;
for (i = 0; i < N; ++ i)
if (S[i] != "")
{
tmp = Get_Cost (i, (1<<N) - 1);
if (tmp > maxim)
{
maxim = tmp;
nod = i;
}
}
//printf ("%d\n", maxim);
Remake (nod, (1<<N) - 1);
printf ("%s\n", sol.c_str());
}
int
main ()
{
freopen ("adn.in", "rt", stdin);
freopen ("adn.out", "wt", stdout);
read ();
solve ();
return 0;
}