Cod sursa(job #1455)

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

using namespace std;

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];
string sir[Nmax],t,p;

void calcpref()
{
    int m=p.size(),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=t.size();
    m=p.size();
    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=t.size();
    m=p.size();
    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,j;    
    printf("%s",sir[permopt[1]].c_str());
    for (i=2;i<=n;i++)
    {
        string s;
        for (j=0+cost[permopt[i-1]][permopt[i]];j<sir[permopt[i]].size();j++)
            s+=sir[permopt[i]][j];
        printf("%s",s.c_str());
    }
}

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

void scrie2(int i,int mask)
{
    ct++;
    permopt[ct]=i;
    if (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++)
        cin>>sir[i];
    for (i=1;i<=n;i++)
        printf("%s\n",sir[i].c_str());    
    
    for (i=1;i<=n;i++)
        for (j=1;j<=n;j++)
            if (i!=j)
                if (sir[i].size()<=sir[j].size())
                {
                    p=sir[i];
                    t=sir[j];
                    if (kmp1())
                        if (sir[i].size()<sir[j].size())
                            w[i]=1;
                        else if (sir[i].size()==sir[j].size())
                            if (i<j)
                                w[i]=1;
                }
    for (i=1;i<=n;i++)
        if (w[i]==0)
        {
            ct++;
            sir[ct]=sir[i];
        }
    n=ct;
    for (i=1;i<=n;i++)
        for (j=1;j<=n;j++)
            if (i!=j)
            {
                t=sir[i];
                p=sir[j];
                cost[i][j]=kmp2();
            }
    ct=0;
    solve();
    scrie2(mx,((1<<n)-1)^(1<<(mx-1)));
    scrie();
    return 0;
}