Pagini recente » Autentificare | Cod sursa (job #2221496) | Cod sursa (job #1934377) | Cod sursa (job #1902407) | Cod sursa (job #2791204)
#include <iostream>
#include <fstream>
#include <string>
#include <vector>
#include <algorithm>
#define inout(f) std::ifstream in((f) + (std::string) ".in");std::ofstream out((f) + (std::string) ".out")
#define d(x) std::cout << x << std::endl
#define dm(msg, x) std::cout << msg << x << std::endl
const int NMAX = 18;
int n;
std::string a[1 + NMAX];
bool skipped[1 + NMAX];
int weights[1 + NMAX][1 + NMAX];
std::vector<std::pair<int, int>> reverseGraph[1 + NMAX];
int dp[(1 << NMAX)][1 + NMAX];
std::pair<int, int> prev[(1 << NMAX)][1 + NMAX];
void removeSkipped() {
int write = 0;
for (int read = 0; read < n; ++read) {
if (!skipped[read]) {
a[write] = a[read];
++write;
}
}
n = write;
}
int cntMatchingCharacters(const std::string& a, const std::string& b) {
std::string concat = "." + b + "." + a;
std::vector<int> pi(concat.size(), 0);
int k = 0;
pi[1] = 0;
for (int i = 2; i < concat.size(); ++i) {
while (k > 0 && concat[k + 1] != concat[i])
k = pi[k];
if (concat[k + 1] == concat[i])
++k;
pi[i] = k;
}
return pi.back();
}
void print(const std::pair<int, int>& current, std::ostream& os) {
if (current.first == 0)
return;
print(prev[current.first][current.second], os);
int edgeWeight = weights[prev[current.first][current.second].second][current.second];
if (prev[current.first][current.second].first == 0)
edgeWeight = 0;
os << a[current.second].substr(edgeWeight);
}
int main() {
inout("adn");
in >> n;
for (int i = 0; i < n; ++i)
in >> a[i];
std::sort(a, a + n, [] (const std::string& i, const std::string& j) -> bool {
return i.size() < j.size();
});
for (int i = 0; i < n; ++i) {
for (int j = i + 1; j < n; ++j) {
if (a[j].find(a[i]) != std::string::npos) {
skipped[i] = true;
break;
}
}
}
removeSkipped();
for (int i = 0; i < n; ++i) {
for (int j = 0; j < n; ++j) {
if (i != j) {
int edgeWeight = cntMatchingCharacters(a[i], a[j]);
weights[i][j] = edgeWeight;
reverseGraph[j].emplace_back(i, edgeWeight);
}
}
}
// hamilton
for (int mask = 0; mask < (1 << n); ++mask) {
for (int last = 0; last < n; ++last) {
dp[mask][last] = -1;
}
}
for (int first = 0; first < n; ++first)
dp[(1 << first)][first] = 0;
for (int mask = 0; mask < (1 << n); ++mask) {
for (int last = 0; last < n; ++last) {
if (!(mask & (1 << last)))
continue;
int newMask = mask ^ (1 << last);
for (const auto& edge: reverseGraph[last]) {
if (mask & (1 << edge.first)) {
if (dp[newMask][edge.first] + edge.second > dp[mask][last]) {
dp[mask][last] = dp[newMask][edge.first] + edge.second;
prev[mask][last] = {newMask, edge.first};
}
}
}
}
}
int len = -1;
std::pair<int, int> best;
for (int i = 0; i < n; ++i) {
if (dp[(1 << n) - 1][i] > len) {
len = dp[(1 << n) - 1][i];
best = {(1 << n) - 1, i};
}
}
print(best, out);
return 0;
}