Cod sursa(job #197332)

Utilizator anna_bozianuBozianu Ana anna_bozianu Data 3 iulie 2008 17:20:08
Problema ADN Scor 100
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.16 kb
#include<stdio.h>
#include<string.h>
#define N 18
#define L 30005
#define M 1<<18
FILE *f,*g;
char s[N][L];
long c[N][N],lung[N],prev[M][N],cc[M][N],inclus[N],
n,m,i,j,k,i8,pi[N][L],h[N],cnt;
void citire();
void prefix();
int KMP();
void precalc();
void pr_dinamica();
void print_sol();
int main()
{
    f=fopen("adn.in","r");g=fopen("adn.out","w");
    citire();
    precalc();
    pr_dinamica();
    print_sol();
    return 0;
}

void citire()
{   char *ss;
    fscanf(f,"%ld",&n);
    m=1<<n;
    i8=1000000000;
    for(i=0;i<n;i++)
    {   ss=&s[i][1];
	s[i][0]=' ';
	fscanf(f,"%s",ss);
	lung[i]=strlen(s[i])-1;
    }
}
void prefix()
{
    int u=0,lsir=lung[i],q;
    pi[i][1]=0;
    for(q=2; q<=lsir;q++)
    {
	while(u>0 && s[i][q]!=s[i][u+1])u=pi[i][u];
	if(s[i][q]==s[i][u+1])u++;
	pi[i][q]=u;
    }
}
int KMP()
{
    int u=0,l1=lung[i],l2=lung[j],q;
    for(q=1; q<=l1; q++)
    {
	while(u>0 && s[i][q]!=s[j][u+1])
	    u=pi[j][u];
	if(s[i][q]==s[j][u+1])
	    u++;
	if(u==l2)
	    return -1;
    }
    return u;
}

void pr_dinamica()
{
    for(i=0;i<m;i++)
     for(j=0;j<n;j++)
	 {   if(!(i&(1<<j)))
		cc[i][j]=i8;
	    else
		if(i==(1<<j))
		    cc[i][j]=lung[j];
		else
		{
		    cc[i][j]=i8;
		    for(k=0;k<n;k++)
			if(cc[i^(1<<j)][k]!=i8 && cc[i][j]>cc[i^(1<<j)][k]+lung[j]-c[k][j])
			{
			    cc[i][j]=cc[i^(1<<j)][k]+lung[j]-c[k][j];
			    prev[i][j]=k;
			}
		}
	 }
}

void print_sol()
{   long t,cuv=0,pu,u=0,cs=0,min=i8;
    for(i=0;i<n;i++)
	if(!inclus[i])cs|=(1<<i);
    for(i=0; i<n; i++)
	if(!inclus[i] && min>cc[cs][i])
	{
	    min=cc[cs][i];
	    u=i;
	}
    while(cs)
    { h[++cuv]=u;
      pu=prev[cs][u];
      cs^=(1<<u);
      u=pu;
    }
    for(;cuv>1;cuv--)
    { t=lung[h[cuv]]-c[h[cuv]][h[cuv-1]];
      for(i=1;i<=t;i++){cnt++;fprintf(g,"%c",s[h[cuv]][i]);}
    }
    t=lung[h[cuv]];
    for(i=1;i<=t;i++){cnt++;fprintf(g,"%c",s[h[cuv]][i]);}
}

void precalc()
{
    for(i=0; i<n; i++)prefix();
    for(i=0; i<n; i++)
     for(j=0; j<n; j++)
     { if(i==j) c[i][j]=0;
       else
	 c[i][j]=KMP();
       if(c[i][j]==-1)
	  inclus[j]=1;
      }
}