Cod sursa(job #308883)

Utilizator Magnuscont cu nume gresit sau fals Magnus Data 28 aprilie 2009 20:16:01
Problema ADN Scor 100
Compilator cpp Status done
Runda tot Marime 3.21 kb
 # include <stdio.h>      
# include <string>      
     
using namespace std;      
     
# define FIN "adn.in"      
# define FOUT "adn.out"      
# define MAXL 30001      
# define MAXN 20      
# define MAXM 1<<18      
     
int N,i,j,k,maxq,mn,mx,f;      
int Prefix[MAXL];      
int C[MAXN][MAXN];      
int D[MAXN][MAXM];      
int U[MAXN][MAXM];      
char s[MAXN][MAXL];      
     
     void prefix(int p)      
     {      
       int i,k,L;      
             
       Prefix[0] = Prefix[1] = k = 0;      
       L = strlen(s[p]+1);      
             
       for (i = 2; i <= L; ++i)      
         {      
            while (k > 0 && s[p][i] != s[p][k+1])      
              k = Prefix[k];      
            if (s[p][i] == s[p][k+1])      
              k++;      
            Prefix[i] = k;      
         }      
     }      
           
     int KMP(int p,int r)      
     {      
        int L,l,i,k;      
              
        L = strlen(s[p]+1);      
        l = strlen(s[r]+1);      
              
        k = 0;      
        for (i = 1; i <= l; ++i)      
          {      
             while (k > 0 && s[p][k+1] != s[r][i])      
               k = Prefix[k];      
             if (s[p][k+1] == s[r][i])      
               k++;      
             if (k == L) return -1;      
          }      
        return k;      
     }      
     
     int main()      
     {      
         freopen(FIN,"r",stdin);      
         freopen(FOUT,"w",stdout);      
               
         scanf("%d\n",&N);      
         for (i = 1; i <= N; ++i)      
           gets(s[i]+1);      
                 
         for (i = 1; i <= N; ++i)      
           for (j = 1; j <= N; ++j)      
             if (i != j)      
               {      
                  prefix(j);      
                  C[i][j] = KMP(j,i);      
                  if (C[i][j] == -1) mn|=(1<<(j-1));      
               }      
         maxq = 1 << N;      
         for (i = 1; i < maxq; ++i)      
           for (j = 1; j <= N; ++j)      
             if (!((1<<(j-1))&i))      
               {      
                 D[j][i] = -1;      
                 for (k = 1; k <= N; ++k)      
                   if ((1<<(k-1))&i)      
                     if (D[k][i-(1<<(k-1))]+C[j][k]>D[j][i])      
                       {      
                          D[j][i]=D[k][i-(1<<(k-1))]+C[j][k];      
                          U[j][i]=k;      
                       }      
               }      
               
         mx = -1; maxq -= 1+mn;      
         for (i = 1; i <= N; ++i)      
           if (D[i][maxq-(1<<(i-1))]>mx)      
             {      
                mx = D[i][maxq-(1<<(i-1))];      
                f = i;      
             }      
         printf("%s",s[f]+1);      
         maxq -= (1<<(f-1));      
         while (maxq > 0)      
           {      
              i = U[f][maxq];      
              mn = strlen(s[i]+1);      
              for (j = C[f][i]+1; j <= mn; ++j)      
                printf("%c",s[i][j]);      
              maxq-=(1<<(i-1));      
              f = i;      
           }      
               
         return 0;      
     }