Pagini recente » Cod sursa (job #1288924) | Cod sursa (job #2406650) | Cod sursa (job #1585420) | Cod sursa (job #2888972) | Cod sursa (job #1571553)
#include <fstream>
#include <cstring>
#include <algorithm>
const int MAX_N = 18;
const int MAX_LEN = 30000;
const int INF = 0x3f3f3f3f;
using namespace std;
char S[MAX_N][MAX_LEN + 1];
int stLength[MAX_N];
int C[MAX_N][MAX_N];
int D[1 << MAX_N][MAX_N];
int from[1 << MAX_N][MAX_N];
int FindCost(int A, int B) {
static char tmp[2 * MAX_LEN + 2];
static int Z[2 * MAX_LEN + 1];
const int m_size = stLength[A] + stLength[B] + 1;
int l, r;
memmove(tmp, S[B], stLength[B]);
tmp[stLength[B]] = '$';
memmove(tmp + stLength[B] + 1, S[A], stLength[A]);
tmp[m_size] = '\0';
l = r = 0;
for (int i = 1; i < m_size; i++) {
if (i <= r)
Z[i] = min(Z[i - l], r - i + 1);
else
Z[i] = 0;
while (tmp[Z[i]] == tmp[i + Z[i]])
Z[i]++;
if (i + Z[i] - 1 > r) {
r = i + Z[i] - 1;
l = i;
}
}
int maxZ = 0;
for (int i = 1 + stLength[B]; i < m_size; i++)
if ((i + Z[i] == m_size || Z[i] == stLength[B]) && (maxZ < Z[i]))
maxZ = Z[i];
return stLength[B] - maxZ;
}
void Reconstituire(int mask, int node, ofstream &out) {
if (mask & (mask - 1)) {
const int fromNode = from[mask][node];
Reconstituire(mask ^ (1 << node), fromNode, out);
out << S[node] + (stLength[node] - C[fromNode][node]);
} else {
out << S[node];
}
}
int main() {
ifstream in("adn.in");
ofstream out("adn.out");
in.tie(0);
ios_base::sync_with_stdio(0);
int N;
int disconsiderMask;
in >> N;
for (int i = 0; i < N; i++) {
in >> S[i];
D[1 << i][i] = stLength[i] = strlen(S[i]);
}
disconsiderMask = 0;
for (int i = 0; i < N; i++)
for (int j = 0; j < N; j++)
if (i != j) {
C[i][j] = FindCost(i, j);
disconsiderMask |= (1 << j) & -(C[i][j] == 0);
}
for (int i = 3; i < (1 << N); i++) {
if (i & (i - 1))
memset(D[i], INF, 4 * N);
}
for (int mask = 1; mask < (1 << N); mask++) {
for (int fn1 = 0; fn1 < N; fn1++) {
if ((mask >> fn1) & 1) {
for (int fn2 = 0; fn2 < N; fn2++) {
const int newMask = mask | (1 << fn2);
const int cost = D[mask][fn1] + C[fn1][fn2];
if ((mask != newMask) && (D[newMask][fn2] > cost)) {
D[newMask][fn2] = cost;
from[newMask][fn2] = fn1;
}
}
}
}
}
int node = 0;
int mask = ((1 << N) - 1) ^ disconsiderMask;
for (int i = 1; i < N; i++) {
if (D[mask][i] < D[mask][node]) {
node = i;
}
}
Reconstituire(mask, node, out);
out.close();
return 0;
}