Pagini recente » Cod sursa (job #1352124) | Cod sursa (job #2936623) | Cod sursa (job #1037974) | Cod sursa (job #936415) | Cod sursa (job #1743712)
using namespace std;
#include <fstream>
#include <vector>
#include <algorithm>
#include <string>
#include <cstring>
using ll = long long;
using uint = unsigned int;
using ull = unsigned long long;
using pii = pair<int, int>;
using pll = pair<ll, ll>;
#define Nmax 18
#define Lmax 30010
#define INF 1000000000
int used, best[1 << Nmax][Nmax], pred[1 << Nmax][Nmax];
char words[Nmax][Lmax];
int G[Nmax][Nmax];
void make_phi(int[], char[]);
int kmp(char[], char[], int[]);
int main()
{
int i, j, k, n, mask;
int phi[Lmax], length[Nmax];
ifstream fin("adn.in");
ofstream fout("adn.out");
(fin >> n).ignore();
for (i = 0; i < n; ++i) { fin.getline(words[i] + 1, Lmax); length[i] = strlen(words[i] + 1); }
for (i = 0; i < n; ++i)
{
make_phi(phi, words[i]);
for (j = 0; j < n; ++j)
if (i != j)
{
int ret = kmp(words[j], words[i], phi);
if (ret == length[i]) { used |= 1 << i; break; }
else G[j][i] = length[i] - ret;
}
}
for (i = 1; i < (1 << n); ++i) for (j = 0; j < n; ++j) best[i][j] = INF;
for (i = 0; i < n; ++i) best[1 << i][i] = length[i];
for (i = 1; i < (1 << n); ++i)
if ((i & used) == 0 && (i & (i - 1)))
{
for (j = 0; j < n; ++j)
if (i & (1 << j))
{
for (k = 0; k < n; ++k)
if (j != k && (i & (1 << k)) && best[i][j] > best[i ^ (1 << j)][k] + G[k][j])
best[i][j] = best[i ^ (1 << j)][k] + G[k][j],
pred[i][j] = k;
}
}
mask = ((1 << n) - 1) ^ used;
for (k = -1, j = 0; j < n; ++j)
{
if ((used & (1 << j)) == 0)
if (k == -1 || best[mask][j] < best[mask][k])
k = j;
}
string sol;
for (i = mask; i; k = j)
{
j = pred[i][k];
i ^= 1 << k;
if(i) sol.insert(sol.begin(), words[k] + length[k] + 1 - G[j][k], words[k] + length[k] + 1);
else sol.insert(sol.begin(), words[k] + 1, words[k] + length[k] + 1);
}
fout << sol << '\n';
fin.close();
fout.close();
return 0;
}
void make_phi(int phi[], char s[])
{
phi[1] = 0;
for (int k = 0, i = 2; s[i]; ++i)
{
while (k && s[i] != s[k + 1]) k = phi[k];
if (s[i] == s[k + 1]) ++k;
phi[i] = k;
}
}
int kmp(char s[], char p[], int phi[])
{
int i, k;
for (k = 0, i = 1; s[i]; ++i)
{
while (k && p[k + 1] != s[i])
k = phi[k];
if (p[k + 1] == s[i]) ++k;
if (p[k + 1] == '\0') return k;
}
return k;
}