Pagini recente » Cod sursa (job #167155) | Cod sursa (job #2828756) | Cod sursa (job #980075) | Cod sursa (job #2292093) | Cod sursa (job #174342)
Cod sursa(job #174342)
#include<stdio.h>
#include<string.h>
FILE*fin=fopen("adn.in","r");
FILE*fout=fopen("adn.out","w");
#define maxn 30001
#define nrconfig 300000
int rez[2][nrconfig][19],p2[19],ad[19][19],sup[2*maxn],n;
char s[19][maxn],t[2*maxn];
void prefix(int x,int y)
{
int i,dim1,dim2,k;
dim1=strlen(s[y]);
for(i=0;i<dim1;i++)
t[i]=s[y][i];
t[dim1]='#';
dim2=strlen(s[x]);
for(i=0;i<dim2;i++)
t[dim1+i+1]=s[x][i];
sup[1]=0;k=0;
for(i=2;i<=dim1+dim2+1;i++)
{
while(k>0&&t[k]!=t[i-1]) k=sup[k];
if(t[k]==t[i-1]) k++;
sup[i]=k;
}
ad[x][y]=sup[dim1+dim2+1];
}
void rec(int config,int ultim)
{
int last=rez[1][config][ultim],cfl=config-p2[ultim-1],i;
if(last==0) fprintf(fout,"%s",s[ultim]);
else
{
rec(cfl,last);
int dim=strlen(s[ultim]);
for(i=ad[last][ultim];i<dim;i++)
fprintf(fout,"%c",s[ultim][i]);
}
}
void pref(int ind)
{
sup[1]=0;int k=0,dim=strlen(s[ind]),i;
for(i=2;i<=dim;i++)
{
while(k>0&&s[ind][k]!=s[ind][i-1]) k=sup[k];
if(s[ind][k]==s[ind][i-1]) k++;
sup[i]=k;
}
}
int kmp(int ind1,int ind2)
{
int k=0,i,dim1=strlen(s[ind1]),dim2=strlen(s[ind2]);
for(i=1;i<=dim1;i++)
{
while(k>0&&s[ind2][k]!=s[ind1][i-1]) k=sup[k];
if(s[ind2][k]==s[ind1][i-1]) k++;
if(k==dim2) return 1;
}
return 0;
}
int main()
{
int i,j,k,lim,ultima_config,dim,ok;
fscanf(fin,"%d",&n);
for(i=1;i<=n;i++)
fscanf(fin,"%s",&s[i]);
fclose(fin);
for(i=1;i<=n;i++)
{
dim=strlen(s[i]);
ok=1;pref(i);
for(j=1;j<i;j++)
if(dim<=strlen(s[j])&&kmp(j,i))
{
ok=0;
break;
}
if(ok)
for(j=i+1;j<=n;j++)
if(dim<=strlen(s[j])&&kmp(j,i))
{
ok=0;
break;
}
if(!ok)
{
for(j=i;j<n;j++)
strcpy(s[j],s[j+1]);
n--;
i--;
}
}
for(i=1;i<=n;i++)
for(j=1;j<=n;j++)
prefix(i,j);
p2[0]=1;
for(i=1;i<=n;i++)
p2[i]=p2[i-1]*2;
lim=p2[n];
for(i=0;i<lim;i++)
for(j=1;j<=n;j++)
rez[0][i][j]=-1;
for(i=0;i<n;i++)
{
rez[0][p2[i]][i+1]=0;
rez[1][p2[i]][i+1]=0;
}
for(i=1;i<lim;i++)
{
for(j=0;j<n;j++)
if(i&p2[j])
{
if(i-p2[j]==0)
break;
ultima_config=i-p2[j];
for(k=0;k<n;k++)
if(ultima_config&p2[k])
if(rez[0][ultima_config][k+1]+ad[k+1][j+1]>rez[0][i][j+1])
{
rez[0][i][j+1]=rez[0][ultima_config][k+1]+ad[k+1][j+1];
rez[1][i][j+1]=k+1;
}
}
}
int max=-1,pmax;
for(j=1;j<=n;j++)
if(rez[0][lim-1][j]>max)
{
max=rez[0][lim-1][j];
pmax=j;
}
rec(lim-1,pmax);
fclose(fout);
return 0;
}