Cod sursa(job #213599)

Utilizator madmanjonesJones the one madmanjones Data 10 octombrie 2008 16:11:37
Problema ADN Scor 100
Compilator cpp Status done
Runda Arhiva de probleme Marime 3.18 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;
     }