Pagini recente » Cod sursa (job #2893540) | Cod sursa (job #408788) | Cod sursa (job #1734825) | Cod sursa (job #2183973) | Cod sursa (job #974196)
Cod sursa(job #974196)
#include<stdio.h>
#include<string.h>
#include<iostream>
#include<string>
#include<vector>
using namespace std;
#define maxl 30005
string sir[20];
int fail[20][maxl];
int sel[20];
int mat[20][20];
int cost[1<<18][18];
int last[1<<18][18];
int cate[1<<18][18];
void prekmp( string sir, int * rez) {
int n = sir.size(), i = 0, j = -1;
rez[0] = -1;
while( i < n ) {
while( j >= 0 && sir[i] != sir[j]) // daca elementele nu sunt compatibile si nu am ajuns inca la inceput
j = rez[j]; // j ia urmataorea valoare posibila
i++; j++;
rez[i] = j;
}
}
int kmp( string sir1, string sir2, int *rez) {
int i = 0, j = 0;
int n = sir1.size(), m = sir2.size();
int nr = 0;
if( m > n ) return 0;
while (i < n ) {
while(j >= 0 && sir1[i] != sir2[j])
j = rez[j];
i++; j++;
if( j == m) {
nr++;
j = rez[j];
}
}
return nr;
}
int semikmp( string sir1, string sir2, int *rez) {
int i = 0, j = 0;
int n = sir1.size(), m = sir2.size();
int nr = 0;
while (i < n ) {
while(j >= 0 && sir1[i] != sir2[j])
j = rez[j];
i++; j++;
if( j == m) {
nr++;
j = rez[j];
}
}
return j;
}
int main() {
freopen("ADN.in", "r", stdin);
freopen("ADN.out", "w", stdout);
int N;
cin>>N;
for( int i = 0; i < N; ++i) {
cin>>sir[i];
prekmp( sir[i], fail[i]);
}
for( int i = 0; i < N; ++i) {
for( int j = i + 1; j < N; ++j) {
sel[j] += kmp( sir[i], sir[j], fail[j]);
sel[i] += kmp( sir[j], sir[i], fail[i]);
}
}
int laast = 0;
for( int i = 0; i < N; ++i) {
if( sel[i] == 0) {
sir[laast++] = sir[i];
for( size_t j = 0; j <= sir[i].size(); ++j) {
fail[laast - 1][j] = fail[i][j];
}
}
}
N = laast;
for( int i = 0; i < N; ++i) {
for( int j = i + 1; j < N; ++j) {
mat[i][j] += semikmp( sir[i], sir[j], fail[j]);
mat[j][i] += semikmp( sir[j], sir[i], fail[i]);
}
}
return 0;
/*
cout<<N<<endl;
for( int i = 0; i < N; ++i)
cout<<sir[i] <<endl;
*/
memset( cost, 111, sizeof(cost));
for( int i = 0; i < N; ++i) {
cost[ 1<<i][i] = sir[i].size();
last[ 1<<i][i] = i;
cate[ 1<<i ][i] = sir[i].size();
}
for( int i = 1; i < (1<<N) - 1; ++i) {
for( int j = 0; j < N; ++j) {
if( (i & ( 1<< j)) == 0)
continue;
for( int k = 0; k < N; ++k){
if( i & (1<<k) )
continue;
if( cost[i ^(1<<k)][k] > cost[i][j] + sir[k].size() - mat[j][k]) {
cost[i ^(1<<k)][k] = cost[i][j] + sir[k].size() - mat[j][k];
last[i ^(1<<k)][k] = j;
cate[i ^(1<<k)][k] = sir[k].size() - mat[j][k];
}
}
}
}
int optim = 1000000000, cine = -1;
for( int i = 0; i < N; ++i)
if( cost[(1<<N)-1][i] < optim) {
optim = cost[(1<<N)-1][i];
cine = i;
}
laast = (1<<N) - 1;
string result;
vector<string> temp_rez;
while( laast ) {
int new_index = cine;
int new_length = cate[laast][cine];
string new_word( sir[new_index].end() - new_length , sir[new_index].end());
temp_rez.push_back(new_word);
int temp_cine = last[laast][cine];
laast ^= (1<<cine);
cine = temp_cine;
}
for( int i = N - 1; i >= 0; i--)
result += temp_rez[i];
//cout<<optim<<endl;
cout<<result;
}