Pagini recente » Cod sursa (job #1362802) | Cod sursa (job #81700) | Cod sursa (job #1385332) | Cod sursa (job #1383100) | Cod sursa (job #430959)
Cod sursa(job #430959)
#include <stdio.h>
#define NMAX 20
#define LMAX 30010
#define HMAX 1<<18
#define INF 1000000000
char A[NMAX][LMAX],marc[NMAX];
int n,L[NMAX],D[NMAX][NMAX],pi[LMAX],match,pot;
int B[NMAX],best[NMAX][HMAX],st,h,rez=INF,poz,ant[NMAX][HMAX];
inline int ok(char x)
{
return x=='A' || x=='G' || x=='C' || x=='T';
}
void read()
{
scanf("%d\n",&n);
int i;
for (i=1; i<=n; i++)
{
fgets(A[i]+1,LMAX,stdin);
while (ok(A[i][L[i]+1]))
L[i]++;
}
}
void prefix(int x)
{
int k=0,i;
for (i=2; i<=L[x]; i++)
{
while (k>0 && A[x][k+1]!=A[x][i])
k=pi[k];
if (A[x][k+1]==A[x][i])
k++;
pi[i]=k;
}
}
void kmp(int x,int y)
{
int i,q=0;
for (i=1; i<=L[x]; i++)
{
while (q>0 && A[y][q+1] != A[x][i])
q=pi[q];
if ( A[y][q+1] == A[x][i])
q++;
if (q==L[y])
pot=1;
match=q;
}
}
void prepare()
{
int i,j;
for (i=1; i<=n; i++)
for (j=1; j<=n; j++)
if (i!=j)
{
prefix(j);
match=pot=0;
kmp(i,j);
if (pot)
marc[j]=1;
D[i][j]=match;
}
}
void get_valid()
{
int i;
for (i=1; i<=n; i++)
if (!marc[i])
B[++st]=i;
h=(1<<st)-1;
}
void init()
{
int i,j;
for (i=1; i<=st; i++)
for (j=1; j<=h; j++)
best[i][j]=INF;
for (i=1; i<=st; i++)
best[i][1<<(i-1)]=L[B[i]];
}
void solve()
{
int i,j,k,t;
for (j=0; j<=h; j++)
for (i=1; i<=st; i++)
if (j & 1<<(i-1))
{
for (k=1; k<=st; k++)
if (!(j & 1<<(k-1)))
{
t=j ^ 1<<(k-1);
if (best[k][t] > best[i][j]+L[B[k]]-D[B[i]][B[k]])
best[k][t]=best[i][j]+L[B[k]]-D[B[i]][B[k]],ant[k][t]=i;
}
}
}
void get_sol()
{
int i;
for (i=1; i<=st; i++)
if (best[i][h]<rez)
rez=best[i][h],poz=i;
}
void reconst(int poz,int stare)
{
if (stare==0)
return ;
int i,poz2=ant[poz][stare],stare2=stare ^ 1<<(poz-1);
reconst(poz2,stare2);
for (i=D[B[poz2]][B[poz]]+1; i<=L[B[poz]]; i++)
printf("%c",A[B[poz]][i]);
}
int main()
{
freopen("adn.in","r",stdin);
freopen("adn.out","w",stdout);
read();
prepare();
get_valid();
init();
solve();
get_sol();
reconst(poz,h);
return 0;
}