Pagini recente » Cod sursa (job #803568) | Cod sursa (job #2655415) | Cod sursa (job #2388068) | Cod sursa (job #1818401) | Cod sursa (job #203347)
Cod sursa(job #203347)
#include <fstream>
#include <string>
using namespace std;
const int LMAX=30001;
int n,pi[LMAX],c[18][18],bad;
string s[18];
ifstream f("adn.in");
ofstream g("adn.out");
void read(){
string aux;
getline(f,aux);
n=atoi(aux.c_str());
for (int i=0;i<n;++i)
getline(f,s[i]);
}
void prefix(string s){
int i,x=0;
memset(pi,0,sizeof(pi));
for (i=1;i<s.size();++i){
while (x>0 && s[x]!=s[i]) x=pi[x-1];
if (s[x]==s[i]) x++;
pi[i]=x;
}
}
int kmp(string s,string t){
//cel mai lung prefix al lui s care este sufix al lui t
int i,x=0;
for (i=0;i<t.size();++i){
while (x>0 && s[x]!=t[i]) x=pi[x-1];
if (s[x]==t[i]) x++;
if (x==s.size()) return -1;
}
return x;
}
void build(){
int i,j;
for (i=0;i<n;++i)
for (j=0;j<n;++j)
if (i!=j){
prefix(s[j]);
c[i][j]=kmp(s[j],s[i]);
if (c[i][j]==-1) bad|=(1<<j);
}
}
int a[18][1<<18],urm[18][1<<18];
void solve(){
int i,j,k,t;
for (j=1;j<(1<<n);++j)
for (i=0;i<n;++i)
if (!((1<<i)&j)) {
a[i][j]=-1;
for (k=0;k<n;++k)
if ((1<<k)&j)
if (a[k][j-(1<<k)]+c[i][k]>a[i][j]){
a[i][j]=a[k][j-(1<<k)]+c[i][k];
urm[i][j]=k;}
}
//aflam maximul
t=-1;j=(1<<n)-1-bad;
for (i=0;i<n;++i)
if (a[i][j-(1<<i)]>t){
k=i;
t=a[i][j-(1<<i)];}
//reconstituim drumul
t=j-(1<<k);
g<<s[k];
while (t>0){
i=urm[k][t];
for (j=c[k][i];j<s[i].size();++j) g<<s[i][j];
t-=(1<<i);
k=i;}
}
int main(){
read();
build();
solve();
return 0;
}