Cod sursa(job #1730974)

Utilizator Bodo171Bogdan Pop Bodo171 Data 17 iulie 2016 23:05:52
Problema ADN Scor 60
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.4 kb
#include <iostream>
#include<fstream>
using namespace std;
int a[20][(1<<18)+5],i,n,j,p[20][30005],k,idx,c[20][20],rasp,cnt;
bool del[25];
string s[20];
char ans[2000005];
struct reconstruct
{
    int l,c;
}tt[20][(1<<18)+5],root;
void calcpref()
{
    p[i][0]=-1;k=-1;
    for(j=1;j<=n;j++)
    {
        while(s[i][j]!=s[i][k+1]&&k!=-1)
            k=p[i][k];
        if(s[i][j]==s[i][k+1])
            k++;
        p[i][j]=k;
    }
}
void calcps()
{
    k=-1;
    for(idx=0;idx<s[j].size();idx++)
    {
      while(k!=-1&&s[i][k+1]!=s[j][idx])
         k=p[i][k];
      if(s[j][idx]==s[i][k+1]) k++;
      if(k==s[i].size()-1) {del[i]=1;}
    }
    k++;
    c[j][i]=s[i].size()-k;
}
int main()
{
    ifstream f("adn.in");
    ofstream g("adn.out");
    f>>n;
    for(i=0;i<n;i++)
        {f>>s[i];}
    for(i=0;i<n;i++)
        calcpref();
    for(i=0;i<n;i++)
        for(j=0;j<n;j++)
    {
        if(i!=j) calcps();
    }
    for(i=0;i<n;i++)
       if(del[i])
    {
        for(j=i+1;j<n;j++)
         s[j-1]=s[j];
        n--;
    }
    for(i=0;i<n;i++)
        {calcpref();}
      for(i=0;i<n;i++)
        for(j=0;j<n;j++)
    {
        if(i!=j) calcps();
    }
    for(i=0;i<n;i++)
        for(j=0;j<(1<<n);j++)
           a[i][j]=1000000;
  for(i=0;i<n;i++)
    {a[i][(1<<i)]=s[i].size();tt[i][(1<<i)].l=19;}
  for(k=1;k<(1<<n);k++)
     {for(i=0;i<n;i++)
        if((k&(1<<i)))
         for(j=0;j<n;j++)
          if(!(k&(1<<j)))
     {
         if(a[i][k]+c[i][j]<a[j][k+(1<<j)])
            {
                a[j][k+(1<<j)]=a[i][k]+c[i][j];
                tt[j][k+(1<<j)].l=i;
                tt[j][k+(1<<j)].c=k;
            }
     }}
     rasp=(1<<30);
     for(i=0;i<n;i++)
        if(a[i][(1<<n)-1]<rasp)
         {rasp=a[i][(1<<n)-1];root.l=i;root.c=(1<<n)-1;}
         rasp--;
         int cpy=rasp;
         bool brk=0;
      while(brk==0)
      {
          i=tt[root.l][root.c].l;
          j=root.l;
          k=s[j].size()-1;
          while(c[i][j]!=0)
          {
              ans[rasp]=s[j][k];
              c[i][j]--;
              rasp--;
              k--;
          }
          cnt++;
          if(tt[root.l][root.c].l!=19)root=tt[root.l][root.c];
          else brk=1;
      }
      i=root.l;
      while(rasp>=0)
      {
          ans[rasp]=s[i][rasp];
          rasp--;
      }
      g<<ans;
    return 0;
}