Pagini recente » Cod sursa (job #257897) | Cod sursa (job #2644145) | Cod sursa (job #2389356) | Cod sursa (job #1713725) | Cod sursa (job #1935829)
#include <iostream>
#include <fstream>
#include <cstring>
#include <vector>
using namespace std;
ifstream fin("adn.in");
ofstream fout("adn.out");
const int MAX = 18;
const int Inf = 0x3f3f3f3f;
int N;
vector<string> a, s;
int D[1<<MAX][MAX];
int b[MAX][MAX];
void Read();
void Solve();
bool Check( string a, string b, int p );
void Write( int conf, int ul, int up );
int main()
{
Read();
Solve();
fin.close();
fout.close();
return 0;
}
void Read()
{
fin >> N; fin.get();
a = vector<string>(N);
for ( int i = 0; i < N; ++i )
{
fin >> a[i];
}
vector<bool> g(N, 0);
for ( int i = 0; i < N; ++i )
for ( int j = 0; j < N; ++j )
if ( i != j && a[i].size() >= a[j].size() && a[i].find(a[j]) != string::npos )
g[j] = true;
int c{0};
for ( int i = 0; i < N; ++i )
if ( !g[i] )
s.push_back(a[i]);
else
++c;
N -= c;
/* for ( int i = 0; i < N; ++i )
fout << s[i] << '\n'; */
}
void Solve()
{
int i, j, k;
for ( i = 0; i < N; ++i )
for ( j = 0; j < N; ++j )
if ( i != j )
{
int t, r;
for ( t = min(s[i].size(), s[j].size()) - 1; t >= 0; --t )
if ( Check(s[i], s[j], t) )
{
r = t;
break;
}
b[i][j] = r;
// fout << s[i] << ' ' << s[j] << ' ' << b[i][j] << '\n';
}
int res{Inf}, u;
for ( i = 0; i < N; ++i )
D[1 << i][i] = s[i].size();
for ( i = 0; i < ( 1 << N ); ++i )
{
int c{0};
for ( j = 0; j < N; ++j )
if ( i & ( 1 << j ) )
++c;
if ( c < 2 )
continue;
for ( j = 0; j < N; ++j )
if ( i & ( 1 << j ) )
{
D[i][j] = Inf;
for ( k = 0; k < N; ++k )
if ( k != j && i & ( 1 << k ) )
{
D[i][j] = min( D[i][j], D[i ^ ( 1 << j )][k] + (int)s[j].size() - b[k][j] );
}
// fout << i << ' ' << j << ' ' << D[i][j] << '\n';
if ( i + 1 == ( 1 << N ) && D[i][j] < res )
res = D[i][j], u = j;
}
}
Write((1 << N) - 1, u, 0);
}
bool Check( string a, string b, int p )
{
if ( p == 0 ) return true;
int i1 = a.size() - p, i2 = 0;
while ( i1 < a.size() )
if ( a[i1++] != b[i2++] )
return false;
return true;
}
void Write( int conf, int ul, int up )
{
for ( int i = 0; i < N; ++i )
if ( i != ul && ( ( 1 << i ) & conf ) && D[conf][ul] == D[conf ^ ( 1 << ul )][i] + (int)s[ul].size() - b[i][ul] )
{
Write(conf ^ ( 1 << ul ), i, b[i][ul]);
break;
}
for ( int i = 0; i < s[ul].size() - up; ++i )
fout << s[ul][i];
}