Cod sursa(job #292375)

Utilizator lexu93Todor Alex lexu93 Data 31 martie 2009 08:41:33
Problema ADN Scor 100
Compilator cpp Status done
Runda Arhiva de probleme Marime 3.56 kb
# include <cstdio>   
# include <string.h>   
# include <algorithm>   
  
using namespace std;   
  
# define FIN "adn.in"   
# define FOUT "adn.out"   
# define MAXN 20   
# define MAXL 30005   
# define MAXM (1<<18)   
  
int N,i,j,Nod,maxq,mx,f,k;   
int P[MAXN];   
int t[MAXN];   
int Prefix[MAXL];   
int C[MAXN][MAXN];   
int D[MAXN][MAXM];   
int U[MAXN][MAXM];   
char s[MAXN][MAXL];   
unsigned char marc[MAXN];   
  
     int cmp(int a, int b)   
     {   
         return strlen(s[a]+1)<strlen(s[b]+1);   
     }   
        
     void prefix(int p)   
     {   
         int i,L,k;   
            
         L = strlen(s[p]+1);   
         Prefix[1] = k = 0;   
         for (i = 2; i <= L; ++i)   
           {   
              while (k && s[p][k+1] != s[p][i])   
                k = Prefix[k];   
              if (s[p][k+1] == s[p][i])   
                k++;   
              Prefix[i] = k;   
           }   
     }   
        
     int KMP(int p, int r)   
     {   
         int L,l,k,i;   
            
         L = strlen(s[p]+1);   
         l = strlen(s[r]+1);   
            
         k = 0;   
         for (i = 1; i <= L; ++i)   
           {   
               while (k && s[p][i] != s[r][k+1])   
                 k = Prefix[k];   
               if (s[p][i] == s[r][k+1])   
                 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);   
             P[i] = i;   
           }   
         sort(P+1,P+N+1,cmp);   
            
         for (i = 1; i <= N; ++i)   
           {   
              prefix(P[i]);   
              for (j = i+1; j <= N; ++j)   
               if (KMP(P[j],P[i]) == -1)   
                 marc[P[i]] = 1;    
           }   
            
         for (i = 1; i <= N; ++i)   
           if (!marc[i])   
             t[++Nod] = i;   
                
         for (i = 1; i <= Nod; ++i)   
           {   
             prefix(t[i]);   
             for (j = 1; j <= Nod; ++j)   
               if (i != j)   
                 C[j][i] = KMP(t[j],t[i]);   
           }   
            
         maxq = (1 << Nod) - 1;   
         for (i = 1; i <= maxq; ++i)   
           for (j = 1; j <= Nod; ++j)   
             if (!((1<<(j-1))&i))   
               {   
                  D[j][i] = -1;   
                  for (k = 1; k <= Nod; ++k)   
                    if (j != k && ((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;   
         for (i = 1; i <= Nod; ++i)   
           if (D[i][maxq-(1<<(i-1))]>mx)   
             {   
                mx = D[i][maxq-(1<<(i-1))];   
                f = i;   
             }   
                
         printf("%s",s[t[f]]+1);   
         mx = maxq-(1<<(f-1));   
         while (mx > 0)   
           {   
              i = U[f][mx];   
              k = strlen(s[t[i]]+1);   
              for (j = C[f][i]+1; j <= k; ++j)   
                printf("%c",s[t[i]][j]);   
              mx -= (1<<(i-1));   
              f = i;   
           }   
            
         return 0;   
     }