Pagini recente » Cod sursa (job #2020606) | Cod sursa (job #1803632) | Cod sursa (job #92941) | Cod sursa (job #913946) | Cod sursa (job #515735)
Cod sursa(job #515735)
#include<stdio.h>
#include<string.h>
#define LCONF (1<<18)+4
#define INF 2000000000
#define minim(a,b) (a<b ? a : b)
int n,sol;
int d[LCONF][20];
int pred[LCONF][20];
int nr[20],c[20][20];
char s[20][30005];
int pi[30005],v[20];
int kmp(int i1,int i2)
{
int i,q=0;
memset(pi,0,sizeof(pi));
for(i=2;i<=nr[i2];i++)
{
while(q>0 && s[i2][q+1]!=s[i2][i])
q=pi[q];
if(s[i2][q+1]==s[i2][i])
q++;
pi[i]=q;
}
q=0;
for(i=1;i<=nr[i1];i++)
{
while(q>0 && s[i1][i]!=s[i2][q+1])
q=pi[q];
if(s[i1][i]==s[i2][q+1])
q++;
if(q==nr[i2])
return nr[i2];
}
return q;
}
// functia de aflare a costului cu KMP
void recur(int cf,int last)
{
if(!cf)
return ;
v[++nr[0]]=last;
recur(cf-(1<<(last-1)),pred[cf][last]);
}
// functia de reconstituire
int main ()
{
int i,j,t,cf,aj=0,cff=0;
freopen("adn.in","r",stdin);
freopen("adn.out","w",stdout);
scanf("%d\n",&n);
for(i=1;i<=n;i++)
{
fgets(s[i]+1,sizeof(s[i])-1,stdin);
nr[i]=strlen(s[i]+1);
while(s[i][nr[i]]!='A'
&& s[i][nr[i]]!='C'
&& s[i][nr[i]]!='G'
&& s[i][nr[i]]!='T')
nr[i]--;
}
// citirea
for(i=1;i<=n;i++)
for(j=1;j<=n;j++)
{
if(i==j)
continue;
c[i][j]=kmp(i,j);
if(c[i][j]==nr[j] && (!(aj&(1<<(j-1)))))
aj+=(1<<(j-1));
}
// calcularea costurilor
for(i=1;i<(1<<n);i++)
{
if(i&aj)
continue;
for(j=1;j<=n;j++)
{
if(!((1<<(j-1))&i))
continue;
cf=i-(1<<(j-1));
if(!cf)
{
d[i][j]=nr[j];
continue;
}
d[i][j]=INF;
for(t=1;t<=n;t++)
{
if(!((1<<(t-1))&cf))
continue;
if(d[cf][t]+nr[j]-c[t][j]<d[i][j])
{
d[i][j]=d[cf][t]+nr[j]-c[t][j];
pred[i][j]=t;
} //if
} //for
} //for
}
// ciclu hamiltonian
cff=(1<<n)-1-aj;
sol=INF;
for(i=1;i<=n;i++)
if(cff&(1<<(i-1)))
sol=minim(sol,d[cff][i]);
for(i=1;i<=n;i++)
if(d[cff][i]==sol)
{
recur(cff,i);
break;
}
// apelarea reconstituirii
for(i=nr[0];i>=1;i--)
for(j=c[v[i+1]][v[i]]+1;j<=nr[v[i]];j++)
printf("%c",s[v[i]][j]);
printf("\n");
// afisarea
return 0;
}