Cod sursa(job #1456)

Utilizator victorsbVictor Rusu victorsb Data 13 decembrie 2006 18:48:45
Problema ADN Scor 100
Compilator cpp Status done
Runda Arhiva de probleme Marime 3.61 kb
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#define Nmax 20
#define Lmax 30005

int n,i,j,w[Nmax],pref[Lmax],ct,cost[Nmax][Nmax],permopt[Nmax],v[Nmax],mx,d[Nmax][1<<18],pas[Nmax][1<<18];
char sir[Nmax][Lmax],t[Lmax],p[Lmax];

void calcpref()
{
    int m=strlen(p),k=0,q,i;
    memset(pref,0,sizeof(pref));
    pref[1]=0;
    for (q=2;q<=m;q++)
    {
        while (k>0&&p[k]!=p[q-1])
            k=pref[k];
        if (p[k]==p[q-1])
            k++;
        pref[q]=k;
    }
}

int kmp1()
{
    int n,m,q,i;
    calcpref();
    n=strlen(t);
    m=strlen(p);
    q=0;
    for (i=1;i<=n;i++)
    {
        while (q>0&&p[q]!=t[i-1])
            q=pref[q];
        if (p[q]==t[i-1])
            q++;
        if (q==m)
            return 1;
    }
    return 0;
}

int kmp2()
{
    int n,m,q,i;
    calcpref();
    n=strlen(t);
    m=strlen(p);
    q=0;
    for (i=1;i<=n;i++)
    {
        while (q>0&&p[q]!=t[i-1])
            q=pref[q];
        if (p[q]==t[i-1])
            q++;
    }
    return q;
}

void scrie()
{
    int i;
    char s[Lmax];
    for (i=1;i<n;i++)
    {
        memset(s,0,sizeof(s));
        strncpy(s,sir[permopt[i]], strlen(sir[permopt[i]]) - cost[permopt[i]][permopt[i+1]] );
        printf("%s",s);
    }
    printf("%s",sir[permopt[n]]);
}

void  solve()
{
    int mask,i,j;
    
    for (i=1;i<=n;i++)
        for (j=0;j<1<<n;j++)
            d[i][j]=-1;
    for (i=1;i<=n;i++)
        d[i][0]=0;
        
    for (mask=0;mask<1<<n;mask++)
        for (i=1;i<=n;i++)
            if (((mask>>(i-1))&1)==1)
                for (j=1;j<=n;j++)
                    if (((mask>>(j-1))&1)==1)
                        if (i!=j)
                            if (d[i][mask^(1<<(i-1))]<d[j][mask^(1<<(j-1))^(1<<(i-1))]+cost[i][j])
                            {
                                d[i][mask^(1<<(i-1))]=d[j][mask^(1<<(j-1))^(1<<(i-1))]+cost[i][j];
                                pas[i][mask^(1<<(i-1))]=j;
                            }
    mx=1;
    mask=(1<<n)-1;
    for (i=2;i<=n;i++)
        if (d[i][mask^(1<<(i-1))]>d[mx][mask^(1<<(mx-1))])
            mx=i;
    /*
    printf("%d\n",mx);
    for (i=1;i<=n;i++)
        printf("%d %d=%d\n",i,mask^(1<<(i-1)),d[i][mask^(1<<(i-1))]);
    */
    
}

void scrie2(int i,int mask)
{
    ct++;
    permopt[ct]=i;
    if (pas[i][mask]!=0)
        scrie2(pas[i][mask],mask^((1<<(pas[i][mask]-1))));
}

int main()
{
    freopen("adn.in","r",stdin);
    freopen("adn.out","w",stdout);
    scanf("%d\n",&n);
    for (i=1;i<=n;i++)
        scanf("%s",sir[i]);
    for (i=1;i<=n;i++)
        for (j=1;j<=n;j++)
            if (i!=j)
                if (strlen(sir[i])<=strlen(sir[j]))
                {
                    memcpy(p,sir[i],sizeof(p));
                    memcpy(t,sir[j],sizeof(t));
                    if (kmp1())
                        if (strlen(sir[i])<strlen(sir[j]))
                            w[i]=1;
                        else if (strlen(sir[i])==strlen(sir[j]))
                            if (i<j)
                                w[i]=1;
                }
    for (i=1;i<=n;i++)
        if (w[i]==0)
        {
            ct++;
            memcpy(sir[ct],sir[i],sizeof(sir[i]));
        }
    n=ct;
    for (i=1;i<=n;i++)
        for (j=1;j<=n;j++)
            if (i!=j)
            {
                memcpy(t,sir[i],sizeof(p));
                memcpy(p,sir[j],sizeof(t));
                cost[i][j]=kmp2();
            }

    solve();    
    ct=0;
    scrie2(mx,((1<<n)-1)^(1<<(mx-1)));
    scrie();    
    return 0;
}