Pagini recente » Cod sursa (job #1861480) | Cod sursa (job #1564896) | Cod sursa (job #3159208) | Cod sursa (job #2263625) | Cod sursa (job #2962637)
// COMPLEXITATE TIMP: O(n*3^n)
// primul, al doilea, al treilea loop (de la 0 la n-1) = O(n)
// al patrulea loop = O(3^n)
// al cincilea, al saselea loop = O(n)
#include <fstream>
#include <cstring>
using namespace std;
ifstream fin("adn.in");
ofstream fout("adn.out");
const int N = 20, M = 1 << 19, L = 90005, INF = 0x3f3f3f3f;
char s[N][L], aux[L];
int a[N][M], sursa[N][M], start[N][N], p[L], bun[L], lungime[N], n;
int prefix(char a[], char b[])
{
memset(p, 0, sizeof(p));
memset(aux, '\0', sizeof(aux));
strcpy(aux + 1, a + 1);
strcat(aux + 1, "*");
strcat(aux + 1, b + 1);
p[0] = -1;
for (int i = 2; aux[i]; i++)
for (int j = p[i - 1]; j >= 0; j = p[j])
if (aux[j + 1] == aux[i])
{
p[i] = j + 1;
break;
}
return p[strlen(aux + 1)];
}
bool verif_string(char a[], char b[])
{
memset(p, 0, sizeof(p));
memset(bun, 0, sizeof(bun));
p[0] = -1;
for (int i = 2; a[i]; i++)
for (int j = p[i - 1]; j >= 0; j = p[j])
if (a[j + 1] == a[i])
{
p[i] = j + 1;
break;
}
int n = strlen(a + 1);
for (int i = 1; b[i]; i++)
for (int j = bun[i - 1]; j >= 0; j = p[j])
if (a[j + 1] == b[i])
{
bun[i] = j + 1;
if (bun[i] == n)
return true;
break;
}
return false;
}
void update(int& x, int val, int& sursa, int a)
{
if (x <= val)
return;
x = val;
sursa = a;
}
void afisare(int x, int cheie)
{
if (cheie == 1 << x)
{
fout << s[x] + 1;
return;
}
afisare(sursa[x][cheie], cheie ^ (1 << x));
fout << s[x] + lungime[x] - start[x][sursa[x][cheie]] + 1;
}
int main()
{
fin >> n;
for (int i = 0; i < n; i++)
{
fin >> s[i] + 1;
lungime[i] = strlen(s[i] + 1);
}
for (int i = 0; i < n; i++)
for (int j = 0; j < n; j++)
{
if (verif_string(s[i], s[j]))
continue;
start[i][j] = lungime[i] - prefix(s[i], s[j]);
}
memset(a, INF, sizeof(a));
for (int i = 0; i < n; i++)
a[i][1 << i] = lungime[i];
for (int j = 1; j < 1 << n; j++)
for (int i = 0; i < n; i++)
for (int k = 0; k < n; k++)
if ((j & (1 << i)) && (j & (1 << k)) == 0)
update(a[k][j | (1 << k)], a[i][j] + start[k][i], sursa[k][j | (1 << k)], i);
int cheie = (1 << n) - 1, cmb = 0;
for (int i = 0; i < n; i++)
if (a[i][cheie] < a[cmb][cheie])
cmb = i;
afisare(cmb, cheie);
fout << "\n";
return 0;
}