Cod sursa(job #1395856)

Utilizator heracleRadu Muntean heracle Data 21 martie 2015 17:03:37
Problema ADN Scor 0
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.24 kb
#include <cstdio>
#include <cstring>

FILE* in=fopen("adn.in","r");
FILE* out=fopen("adn.out","w");

const int Q=30008,INF=2000000000;

int n;

char v[19][Q];
int to;

int b[Q];

int prst;

int ask_kmp(char t[Q], int x)
{
    int s=strlen(t+1);

    while(t[s]<'A' || t[s]>'Z')
        s--;

    int p=0;

    for(int i=1; i<=s; i++)
    {
        while(p && t[i]!=v[x][p+1])
            p=b[p];
        if(t[i]==v[x][p+1])
            p++;

        if(v[x][p+1]=='\n' || v[x][p+1]==0)
        {
            prst|=1<<x;
        }
    }

    return p;
}

void make_kmp(char v[Q])
{
    int s=strlen(v+1);

    while(v[s]<'A' || v[s]>'Z')
        s--;

    to=s;
    int p=0;

    for(int i=2; i<=s; i++)
    {
        while(p && v[i]!=v[p+1])
            p=b[p];
        if(v[i]==v[p+1])
            p++;
        b[i]=p;
    }
}

int mat[19][19];

int val[1<<18][18];

int frm[1<<18][18];

void recurs(int poz, int last)
{
    if(last==-1)
        return ;



    int sar=0;

    if(frm[poz][last]!=-1)
        sar=mat[frm[poz][last]][last];

    sar++;


    for(int k=sar; v[last][k] && v[last][k]!='\n'; k++)
        fprintf(out,"%c",v[last][k]);




    recurs(poz-(1<<last),frm[poz][last]);




}

int main()
{
    fscanf(in,"%d\n",&n);

    for(int i=0; i<n; i++)
        fgets(v[i]+1,Q,in);


    for(int i=0; i<n; i++)
    {
        make_kmp(v[i]);
        for(int j=0; j<n; j++)
        {
            if(i==j)
                continue;

            mat[i][j]=ask_kmp(v[j],i);
        }
    }

    int to=1<<n;

    for(int i=1; i<to; i++)
    {
        if((i&prst) !=0 )
            continue;
        for(int k=0; k<n; k++)
        {
            frm[i][k]=-1;
            if((i>>k)&1)
            {
                for(int p=0; p<n; p++)
                {
                    if(p!=k && ((i>>p)&1))
                    {
                        if(val[i][k]<val[i-(1<<k)][p]+mat[p][k])
                        {
                            val[i][k]=val[i-(1<<k)][p]+mat[p][k];
                            frm[i][k]=p;
                        }
                    }
                }
            }
        }
    }

    int max=0;

    for(int i=1; i<n; i++)
    {
        if(val[to-prst-1][i]>val[to-prst-1][max])
            max=i;
    }

    recurs(to-prst-1,max);



    return 0;
}