Cod sursa(job #392966)

Utilizator freak93Adrian Budau freak93 Data 8 februarie 2010 17:41:15
Problema ADN Scor 50
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.53 kb
#include<cstdio>
#include<cstring>
#include<algorithm>

using namespace std;

const char iname[]="adn.in";
const char oname[]="adn.out";
const int maxn=19;
const int maxl=32005;
const int INF=(1<<29)-1;

char s[maxn][maxl],ans[maxl*maxn];

int pi[maxl],i,j,n,mod,inside[maxn],len[maxn],cost[maxn][maxn],a[1<<maxn][maxn],mint,x,minx,r;

void build_prefix(int x)
{
    int k=0,i;
    for(i=2;i<=len[x];++i)
    {
        while(k&&s[x][i]!=s[x][k+1])
            k=pi[k];
        if(s[x][i]==s[x][k+1])
            ++k;
        pi[i]=k;
    }
}

void kmp(int x,int y)
{
    int k=0,i;
    for(i=1;i<=len[y];++i)
    {
        while(k&&s[y][i]!=s[x][k+1])
            k=pi[k];
        if(s[y][i]==s[x][k+1])
        {
            ++k;
            if(k==len[x])
                inside[x]=true;
        }
    }
    cost[y][x]=len[x]-k;
}

int sol(int bytes,int last)
{
    if(a[bytes][last]==-1)
    {
        a[bytes][last]=INF;
        for(int i=0;i<n;++i)
            if(i!=last&&(1<<i)&bytes)
                a[bytes][last]=min(a[bytes][last],sol(bytes-(1<<last),i)+cost[i][last]);
    }

    return a[bytes][last];
}

void show(int bytes,int last)
{
    if(bytes==(1<<last))
    {
        strcpy(ans+r,s[last]+1);
        r+=strlen(s[last]+1);
        return;
    }
    int minx=5,x,mint=INF;
    for(int i=0;i<n;++i)
        if(i!=last&&(1<<i)&bytes&&a[bytes-(1<<last)][i]!=-1)
        {
            x=a[bytes-(1<<last)][i]+cost[i][last];
            if(x<mint)
                mint=x,minx=i;
        }
    show(bytes-(1<<last),minx);
    strcpy(ans+r,s[last]+(len[last]-cost[minx][last]+1));
    r+=strlen(s[last]+(len[last]-cost[minx][last]+1));
}

int main()
{
    freopen(iname,"r",stdin);
    freopen(oname,"w",stdout);

    scanf("%d\n",&n);
    for(i=0;i<n;++i)
    {
        fgets(s[i]+1,sizeof(s[i]),stdin);
        len[i]=strlen(s[i]+1);
        if(s[i][len[i]]=='\n')
            s[i][len[i]--]=0;
    }

    for(i=0;i<n;++i)
    {
        build_prefix(i);
        for(j=0;j<n;++j)
            if(i!=j)
                kmp(i,j);
    }

    memset(a,-1,sizeof(a));
    for(i=0;i<n;++i)
        a[1<<i][i]=0;

    mod=(1<<n)-1;
    for(i=0;i<n;++i)
        if(inside[i])
            mod-=(1<<i);
    mint=INF;
    for(i=0;i<n;++i)
        if(inside[i]==0)
        {
            x=sol(mod,i);
            if(x<mint)
                mint=x,minx=i;
        }

    show(mod,minx);
    printf("%s\n",ans);

    fclose(stdin);
    fclose(stdout);

    return 0;
}