Pagini recente » Cod sursa (job #2585663) | Cod sursa (job #979654) | Cod sursa (job #2287236) | Cod sursa (job #2374202) | Cod sursa (job #2240958)
#include <iostream>
#include <fstream>
#include <cstring>
#include <bitset>
#include <vector>
using namespace std;
ifstream in("adn.in");
ofstream out("adn.out");
const int NMAX = 3 * 1e4;
const int VMAX = 20;
const int SMAX = (1 << 18) + 20;
int n;
int sum, root;
int d[1 + NMAX];
int p[VMAX][SMAX];
int dp[VMAX][SMAX];
int cost[VMAX][VMAX];
string s[VMAX];
vector < int > sol;
bitset < VMAX > del;
int kmp(string &a, string &b) {
int k = 0;
for(int i = 1; i < a.size(); i++) {
while(k != 0 && a[i] != a[k])
k = d[k - 1];
if(a[i] == a[k])
k++;
d[i] = k;
}
k = 0;
for(int i = 0; i < b.size(); i++) {
while (k != 0 && b[i] != a[k])
k = d[k - 1];
if(b[i] == a[k])
k++;
}
return k;
}
bool check(string &a, string &b) {
int k = 0;
for(int i = 1; i < a.size(); i++) {
while(k != 0 && a[i] != a[k])
k = d[k - 1];
if(a[i] == a[k])
k++;
d[i] = k;
}
k = 0;
for(int i = 0; i < b.size(); i++) {
while(k != 0 && b[i] != a[k])
k = d[k - 1];
if(b[i] == a[k])
k++;
if(k == a.size())
return true;
}
return false;
}
int main()
{
in >> n;
for(int i = 1; i <= n; i++) {
in >> s[i];
}
for(int i = 1; i <= n; i++) {
for(int j = 1; j <= n; j++) {
if(i != j && del[i] == 0 && del[j] == 0 && s[i].size() <= s[j].size())
if(check(s[i], s[j]))
del[i] = 1;
}
}
for(int i = 1; i <= n; i++) {
while(del[i] && i <= n) {
swap(s[i], s[n]);
if(del[n] == 0)
del[i] = 0;
else
del[i] = 1;
n--;
}
}
for(int i = 1; i <= n; i++) {
for(int j = 1; j <= n; j++) {
if(i != j) {
cost[i - 1][j - 1] = kmp(s[j], s[i]);
}
}
}
for(int i = 0; i < (1 << n); i++) {
for(int j = 0; j < n; j++) {
p[j][i] = -1;
if(i & (1 << j)) {
for(int k = 0; k < n; k++) {
if(i & (1 << k)) {
if(dp[k][i ^ (1 << j)] + cost[j][k] > dp[j][i]) {
p[j][i] = k;
dp[j][i] = dp[k][i ^ (1 << j)] + cost[j][k];
}
}
}
}
}
}
for(int i = 0; i < n; i++) {
if(sum < dp[i][(1 << n) - 1]) {
sum = dp[i][(1 << n) - 1];
root = i;
}
}
int i = (1 << n) - 1;
while(root != -1) {
sol.push_back(root + 1);
int aux = p[root][i];
i -= (1 << root);
root = aux;
}
root = sol.front();
out << s[root];
for(int i = 1; i < sol.size(); i++) {
int from = cost[root - 1][sol[i] - 1];
out << s[sol[i]].substr(from);
root = sol[i];
}
out << '\n';
in.close();
out.close();
return 0;
}