Pagini recente » Cod sursa (job #3193964) | Cod sursa (job #2893533) | Cod sursa (job #2615375) | Cod sursa (job #3157688) | Cod sursa (job #3138093)
#include <stdio.h>
#include <string.h>
#define maxl 30010
#define maxn 19
#define maxx 40
#define maxm 262144
#define maxval 1000000000
char s[maxn][maxl];
int n,l,sol;
int a[maxn][maxx],b[maxn][maxx],p[maxn][maxx],grad[maxn],len[maxn];
int t[maxx];
int c[maxn][maxm],p1[maxn][maxm],p2[maxn][maxm];
int h[maxm],v[maxm];
char g[maxm],v2[maxm];
void prefix(int k)
{
int i,x=-1;
t[0]=-1;
for (i=1;i<=len[k];i++)
{
while ((x>-1) && (s[k][x+1]!=s[k][i])) x=t[x];
if (s[k][x+1]==s[k][i]) x++;
t[i]=x;
}
}
int KMP(int j,int k)
{
int i,x=-1;
x=-1;
for (i=0;i<=len[j];i++)
{
while ((x>-1) && (s[k][x+1]!=s[j][i])) x=t[x];
if (s[k][x+1]==s[j][i]) x++;
}
return len[k]-x;
}
int fits(int j,int k)
{
int i,x=-1;
x=-1;
for (i=0;i<=len[j];i++)
{
while ((x>-1) && (s[k][x+1]!=s[j][i])) x=t[x];
if (s[k][x+1]==s[j][i]) x++;
if (x==len[k]) return 1;
}
return 0;
}
int count(int x)
{
int rez=0;
while (x>0)
{
rez=rez+x%2;
x=x>>1;
}
return rez;
}
void arrange(int p,int r)
{
int q=(p+r)/2,i=p,j=q+1,l=p-1;
while ((i<=q) && (j<=r))
{
l++;
if (g[i]<=g[j])
{
v[l]=h[i];
v2[l]=g[i];
i++;
}
else {
v[l]=h[j];
v2[l]=g[j];
j++;
}
}
while (i<=q)
{
l++;
v[l]=h[i];
v2[l]=g[i];
i++;
}
while (j<=r)
{
l++;
v[l]=h[j];
v2[l]=g[j];
j++;
}
for (i=p;i<=r;i++)
{
h[i]=v[i];
g[i]=v2[i];
}
}
void merge(int p,int r)
{
if (p<r)
{
int q=(p+r)/2;
merge(p,q);
merge(q+1,r);
arrange(p,r);
}
}
int max(int x,int y)
{
if (x>y) return x;
return y;
}
void print(int x,int y)
{
if (x==0) return;
else {
int x2=p1[x][y],y2=p2[x][y];
print(x2,y2);
int i;
for (i=max(len[x]-(c[x][y]-c[x2][y2])+1,0);i<=len[x];i++) printf("%c",s[x][i]);
}
}
int main()
{
freopen("adn.in","r",stdin);
freopen("adn.out","w",stdout);
int i,j,k,x;
scanf("%d ",&n);
for (i=1;i<=n;i++)
{
scanf("%s\n",&s[i]);
len[i]=strlen(s[i])-1;
}
for (i=1;i<=n;i++)
{
prefix(i);
for (j=1;j<=n;j++)
if (i!=j)
{
grad[j]++;
a[j][grad[j]]=i;
b[j][grad[j]]=KMP(j,i);
p[j][grad[j]]=i;
}
for (j=1;j<=n;j++)
if ((i!=j) && (len[j]>=len[i]) && (fits(j,i)))
{
grad[j]++;
a[j][grad[j]]=i;
b[j][grad[j]]=0;
p[j][grad[j]]=j;
}
}
l=(1<<n)-1;
for (i=1;i<=l;i++)
{
h[i]=i;
g[i]=count(i);
}
merge(1,l);
for (i=1;i<=n;i++)
for (j=1;j<=l;j++) c[i][j]=maxval;
for (i=0;i<=n;i++) c[i][0]=0;
for (i=1;i<=n;i++) c[i][1<<(i-1)]=len[i]+1;
for (i=1;i<=l;i++)
for (j=1;j<=n;j++)
for (k=1;k<=grad[j];k++)
if (((h[i]&(1<<(a[j][k]-1)))==0) && (c[j][h[i]]+b[j][k]<c[p[j][k]][h[i]+(1<<(a[j][k]-1))]))
{
c[p[j][k]][h[i]+(1<<(a[j][k]-1))]=c[j][h[i]]+b[j][k];
p1[p[j][k]][h[i]+(1<<(a[j][k]-1))]=j;
p2[p[j][k]][h[i]+(1<<(a[j][k]-1))]=h[i];
}
sol=maxval;
for (i=1;i<=n;i++)
if (c[i][l]<sol)
{
sol=c[i][l];
x=i;
}
// printf("%d\n",sol);
print(x,l);
printf("\n");
return 0;
}