Pagini recente » Cod sursa (job #1878620) | Cod sursa (job #1751646) | Cod sursa (job #1140944) | Cod sursa (job #222587) | Cod sursa (job #594595)
Cod sursa(job #594595)
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const char iname[]="adn.in";
const char oname[]="adn.out";
const int maxn=19;
const int maxl=32005;
const int INF=(1<<29)-1;
char s[maxn][maxl],ans[maxl*maxn];
int pi[maxl],i,j,n,mod,inside[maxn],len[maxn],cost[maxn][maxn],a[1<<maxn][maxn],mint,x,minx,r;
void build_prefix(int x)
{
int k=0,i;
for(i=2;i<=len[x];++i)
{
while(k&&s[x][i]!=s[x][k+1])
k=pi[k];
if(s[x][i]==s[x][k+1])
++k;
pi[i]=k;
}
}
void kmp(int x,int y)
{
int k=0,i;
for(i=1;i<=len[y];++i)
{
while(k&&s[y][i]!=s[x][k+1])
k=pi[k];
if(s[y][i]==s[x][k+1])
{
++k;
if(k==len[x])
inside[x]=1;
}
}
cost[y][x]=len[x]-k;
}
int sol(int bytes,int last)
{
if(a[bytes][last]==-1)
{
a[bytes][last]=INF;
for(int i=0;i<n;++i)
if(i!=last&&(1<<i)&bytes)
a[bytes][last]=min(a[bytes][last],sol(bytes-(1<<last),i)+cost[i][last]);
}
return a[bytes][last];
}
void show(int bytes,int last)
{
if(bytes==(1<<last))
{
strcpy(ans+r,s[last]+1);
r+=strlen(s[last]+1);
return;
}
int minx=5,x,mint=INF;
for(int i=0;i<n;++i)
if(i!=last&&(1<<i)&bytes&&a[bytes-(1<<last)][i]!=-1)
{
x=a[bytes-(1<<last)][i]+cost[i][last];
if(x<mint)
mint=x,minx=i;
}
show(bytes-(1<<last),minx);
strcpy(ans+r,s[last]+(len[last]-cost[minx][last]+1));
r+=strlen(s[last]+(len[last]-cost[minx][last]+1));
}
int main()
{
freopen(iname,"r",stdin);
freopen(oname,"w",stdout);
scanf("%d\n",&n);
for(i=0;i<n;++i)
{
fgets(s[i]+1,sizeof(s[i]),stdin);
len[i]=strlen(s[i]+1);
if(s[i][len[i]]=='\n')
s[i][len[i]--]=0;
}
for(i=0;i<n;++i)
{
build_prefix(i);
for(j=0;j<n;++j)
if(i!=j)
kmp(i,j);
}
memset(a,-1,sizeof(a));
for(i=0;i<n;++i)
if(inside[i]==0)
a[1<<i][i]=strlen(s[i]+1);
mod=(1<<n)-1;
for(i=0;i<n;++i)
if(inside[i])
mod-=(1<<i);
mint=INF;
for(i=0;i<n;++i)
if(inside[i]==0)
{
x=sol(mod,i);
if(x<mint)
mint=x,minx=i;
}
show(mod,minx);
printf("%s\n",ans);
fclose(stdin);
fclose(stdout);
return 0;
}