Cod sursa(job #1012002)

Utilizator dariusdariusMarian Darius dariusdarius Data 17 octombrie 2013 21:22:12
Problema ADN Scor 100
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.43 kb
#include<cstdio>
#include<algorithm>
#include<cstring>
using namespace std;
char s[18][30005];
int n,len[18],a[18][18];
int d[1<<18][18];
int p[1<<18][18];
char S[60005];
int pi[18][30005];
void prefix(char s[30005],int pi[30005],int n)
{
    pi[1]=0;int k=0;
    for(int i=2;i<=n;i++)
    {
        while(k>0 && s[k+1]!=s[i])
            k=pi[k];
        if(s[k+1]==s[i])
            k++;
        pi[i]=k;
    }
}
int kmp(char s1[30005],char s2[30005],int n,int m,int pi[30005])
{
    int k=0;
    for(int i=1;i<=n;i++)
    {
	while(k>0 && s1[i]!=s2[k+1])
		k=pi[k];
	if(s1[i]==s2[k+1])
		k++;
    }
    return k;
}
int solve(int c,int i)
{
    if(c==(1<<i))
        return len[i];
    if(d[c][i])
        return d[c][i];
    d[c][i]=1000000000;p[c][i]=-1;
    for(int j=0;j<n;j++)
        if(i!=j && (c&(1<<j))!=0)
        {
            int aux=solve(c^(1<<i),j);
            if(aux+len[i]-a[j][i]<d[c][i])
            {
                d[c][i]=aux+len[i]-a[j][i];
                p[c][i]=j;
            }
        }
    return d[c][i];
}
void afis(int c,int i)
{
    if(c==(1<<i))
    {
        printf("%s",s[i]+1);
    	fprintf(stderr,"%d ", i);
    }
    else
    {
        afis(c^(1<<i),p[c][i]);
        fprintf(stderr,"%d ",i);
	for(int poz=a[p[c][i]][i]+1;poz<=len[i];poz++)
            putchar(s[i][poz]);
    }
}
int main()
{
    freopen("adn.in","r",stdin);
    freopen("adn.out","w",stdout);
    scanf("%d\n",&n);
    for(int i=0;i<n;i++)
	gets(s[i]+1);
    while(1)
    {
	bool flag=false;
	for(int i=0;i<n && !flag;i++)
		for(int j=0;j<n && !flag;j++)
			if(i!=j && strstr(s[i]+1,s[j]+1))
			{
				flag=true;
				for(int k=j+1;k<n;k++)
					memcpy(s[k-1],s[k],sizeof(s[k]));
				memset(s[n-1],0,sizeof(s[n-1]));
				n--;
			}
	if(flag==false)
		break;
    }
    for(int i=0;i<n;i++)
    {
	len[i]=strlen(s[i]+1);
        prefix(s[i],pi[i],len[i]);
    }
    for(int i=0;i<n;i++)
        for(int j=0;j<n;j++)
            if(i!=j)
                a[i][j]=kmp(s[i],s[j],len[i],len[j],pi[j]);
    int ind=0,T=solve((1<<n)-1,0);
    for(int i=1;i<n;i++)
        if(solve((1<<n)-1,i)<=T)
        {
            T=solve((1<<n)-1,i);
	    ind=i;
        }
    for(int i=0;i<n;i++)
	fprintf(stderr,"%d\n",d[(1<<n)-1][i]);
    fprintf(stderr,"\n%d\n",ind);
    fprintf(stderr,"\nLENGTH: %d\n",T);
    afis((1<<n)-1,ind);
    printf("\n");
    fprintf(stderr,"\n");
    for(int i=0;i<n;i++)
	fprintf(stderr,"%s\n",s[i]+1);
    fprintf(stderr,"%d %d\n",a[0][2],a[2][0]);
    return 0;
}