Pagini recente » Cod sursa (job #991769) | Cod sursa (job #1626548) | Cod sursa (job #1529614) | Cod sursa (job #1602719) | Cod sursa (job #1556050)
#include <stdio.h>
#include <cstring>
char s[19][30005];
int lungime[20];
char sir[60005];
int z[60005];
int l;
int eliminat[20];
int cost[20][20];
int sol[20][300005];
int drum[20][300005];
int put[20];
int main()
{
freopen("adn.in","r",stdin);
freopen("adn.out","w",stdout);
int n;
scanf("%d\n",&n);
for (int i=1; i<=n; ++i)
{
gets(s[i]);
lungime[i] = strlen(s[i]);
}
for (int i=1; i<=n; ++i)
{
for (int j=1; j<=n; ++j)
{
if(i!=j)
{
l = lungime[i] + lungime[j] + 1;
for (int ind=0; ind<lungime[i]; ++ind)
{
sir[ind] = s[i][ind];
z[ind] = 0;
}
sir[lungime[i]] = '#';
for (int ind=0; ind<lungime[j]; ++ind)
{
sir[ind+lungime[i] + 1] = s[j][ind];
z[ind+lungime[i] + 1] = 0;
}
int st=0,dr=0;
for (int ind=1; ind<l; ++ind)
{
if(ind > dr)
{
st = ind; dr = ind;
while (dr<l && sir[dr] == sir[dr-st]) ++dr;
z[ind]=dr-st;
--dr;
}else
{
if (z[ind-st] < dr-ind+1)
{
z[ind] = z[ind-st];
}else
{
st=ind;
while (dr<l && sir[dr] == sir[dr-ind]) ++dr;
z[ind] = dr - st;
--dr;
}
}
if (ind>lungime[i])
if (z[ind] == lungime[i])
{
if (eliminat[i]==0) ++eliminat[0];
eliminat[i]=1;
}else
{
if (ind+z[ind] == l && cost[j][i]<z[ind]) { cost[j][i]=z[ind]; }
}
}
}
}
}
put[1] = 1;
for (int i=2; i<=n; ++i)
{
put[i] = put[i-1]*2;
}
int val=1<<(n-eliminat[0]);
int stare[20]; for (int i=0; i<20; ++i) stare[i]=0;
while (val > 0)
{
int i=1; while (stare[i] == 1 || (stare[i]==0 && eliminat[i]==1)) {stare[i]=0; ++i; } stare[i]=1;
int nr = 0;
for (int i=1; i<=n; ++i)
{
nr += put[i]*stare[i];
}
for (int i=1; i<=n; ++i)
{
if (stare[i] == 1)
{
stare[i]=0;
nr-=put[i];
for (int j=1; j<=n; ++j)
{
if (stare[j]==1)
{
int nr2 = nr-put[j];
if (cost[i][j]+sol[j][nr2] > sol[i][nr]) { sol[i][nr] = cost[i][j]+sol[j][nr2]; drum[i][nr]=j; }
}
}
nr+=put[i];
stare[i]=1;
}
}
--val;
}
int nr = 0; for (int i=1; i<=n; ++i) { if (eliminat[i]==0) nr+=put[i]; }
int maxim=-1;
int care=0;
for (int i=1; i<=n;++i)
{
if (eliminat[i]==0) if (sol[i][nr-put[i]]>maxim) { maxim=sol[i][nr-put[i]]; care=i;}
}
if (care==0) { maxim=-1; for (int i=1; i<=n; ++i) { if (maxim<lungime[i]) { maxim=lungime[i]; care=i; } } }
nr-=put[care];
printf("%s",s[care]);
while (nr > 0)
{
int nou = drum[care][nr];
printf("%s",(char*)(s[nou]+cost[care][nou]));
care = nou;
nr-=put[care];
}
fclose(stdin);
fclose(stdout);
return 0;
}