Pagini recente » Cod sursa (job #1612356) | Cod sursa (job #1973304) | Cod sursa (job #1953610) | Cod sursa (job #2447998) | Cod sursa (job #1148245)
#include <fstream>
//#include <iostream>
#include <vector>
#include <string>
using namespace std;
ifstream fin ("adn.in");
ofstream fout ("adn.out");
const int N = 18, SZ = 30005;
#define nod first
#define stare second
string s[N];
int n, d[N][1 << N], a[N][N], best;
pair <int, int> t[N][1 << N];
bool match[N];
int Dyn (int x, int st) {
if (d[x][st] != -1)
return d[x][st];
d[x][st] = 0;
for (int i = 0; i < n; ++i)
if (x != i && (1 << i) & st && !match[i]) {
if (d[x][st] < Dyn(i, st - (1 << i)) + a[i][x]) {
d[x][st] = d[i][st - (1 << i)] + a[i][x];
t[x][st].nod = i;
t[x][st].stare = st - (1 << i);
}
}
return d[x][st];
}
int kmp(string &a, string &b, bool det) {
if (det && a.size() > b.size())
return 0;
vector <int> U(SZ, 0);
int k = 0, sz_a = a.size() - 1, sz_b = b.size() - 1;
for (int i = 2; i <= sz_a; ++i) {
while (k && a[k+1] != a[i])
k = U[k];
if (a[k+1] == a[i])
k++;
U[i] = k;
}
k = 0;
for (int i = 1; i <= sz_b; ++i) {
while (k && a[k+1] != b[i])
k = U[k];
if (a[k+1] == b[i])
k++;
if (k == sz_a) {
if (det)
return 1;
if (i != sz_b)
k = U[k];
}
}
if (det)
return 0;
return k;
}
void write(int node, int st) {
if (st)
write (t[node][st].nod, t[node][st].stare);
else
return;
if (!t[node][st].stare) {
for (int i = 1; i < s[node].size(); ++i)
fout << s[node][i];
return;
}
for (int i = 1; i < s[node].size() - a[t[node][st].nod][node]; ++i)
fout << s[node][i];
//fout << "\n";
}
int main() {
fin >> n;
for (int i = 0; i < n; ++i) {
string Input;
fin >> Input;
s[i] = ' ' + Input;
}
for (int i = 0; i < n; ++i)
for (int j = 0; j < n; ++j)
if (i != j && kmp(s[i], s[j], 1))
match[i] = 1;
for (int i = 0; i < n; ++i)
for (int j = 0; j < n; ++j)
if (i != j && !match[i] && !match[j])
a[i][j] = kmp(s[i], s[j], 0);
/*for (int i = 0; i < n; ++i) {
for (int j = 0; j < n; ++j)
cout << a[i][j] << " ";
cout << "\n";
}*/
for (int i = 0; i < n; ++i)
for (int j = 0; j < (1 << n); ++j)
d[i][j] = -1;
for (int i = 0; i < n; ++i)
if (!match[i])
best = max(best, Dyn(i, (1 << n) - 1 - (1 << i)));
for (int i = 0; i < n; ++i)
if (d[i][(1 << n) - 1 - (1 << i)] == best)
write(i, (1 << n) - 1 - (1 << i));
//fout << "\n" << best;
}