Cod sursa(job #307328)

Utilizator BabanuBarbieru Irineu Babanu Data 23 aprilie 2009 22:28:33
Problema ADN Scor 100
Compilator cpp Status done
Runda Arhiva de probleme Marime 3.95 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;      
     }