Cod sursa(job #2587041)

Utilizator popashtefan10Popa Stefan popashtefan10 Data 21 martie 2020 22:04:40
Problema ADN Scor 0
Compilator cpp-64 Status done
Runda Arhiva de probleme Marime 1.95 kb
#include <iostream>
#include <cstdio>
#include <cstring>
#define NMAX 18
#define LMAX 30000

using namespace std;

int n, p18 = 1 << 18;
int l[NMAX];
int urm[LMAX + 5];
int d[1 << NMAX][NMAX][2]; /// tin minte si de unde am venit
char s[NMAX][LMAX + 5];
char p[2 * LMAX + 5];

int prefix(char *pattern, int lp, int l1) {
  int k, bestk = 0;

  urm[0] = 0;
  for(int i = 1; i < lp; i++) {
    k = urm[i - 1];
    while(k > 0 && pattern[i] != pattern[k])
      k = urm[k - 1];
    if(pattern[i] == pattern[k])
      k++;
    urm[i] = k;
    bestk = max(bestk, k);
  }
  return bestk;
}

void get_adn(int ind, int bm) {
  if(d[bm][ind][1] == -1)
    printf("%s", s[ind]);
  else {
    int old_bm = bm ^ (1 << ind), dad = d[bm][ind][1], old_l = d[old_bm][dad][0], crt_l = d[bm][ind][0];
    get_adn(dad, old_bm);
    printf("%s", s[ind] + l[ind] -  crt_l + old_l);
  }
}

int main() {
  freopen("adn.in", "r", stdin);
  freopen("adn.out", "w", stdout);
  int pn;

  scanf("%d ", &n);
  pn = 1 << n;
  for(int i = 0; i < n; i++) {
    scanf("%s", &s[i]);
    l[i] = strlen(s[i]);
  }

  for(int bm = 1; bm < pn; bm++)
    for(int i = 0; i < n; i++)
      if(bm & (1 << i)) {
        int nbm = bm ^ (1 << i);

        if(nbm == 0)
          d[bm][i][0] = l[i], d[bm][i][1] = -1;
        else {
          strncpy(p, s[i], l[i]);
          for(int j = 0; j < n; j++)
            if(nbm & (1 << j)) {
              strncpy(p + l[i], s[j], l[j]);
              int ll = prefix(p, l[i] + l[j], l[i]);
              if(d[bm][i][0] == 0 || d[nbm][j][0] - ll + l[i] < d[bm][i][0]) {
                d[bm][i][0] = d[nbm][j][0] - ll + l[i];
                d[bm][i][1] = j;
              }
            }
        }
      }

  int minim = 18 * LMAX + 5, pozmin;
  for(int i = 0; i < n; i++)
    if(d[pn - 1][i][0] != 0 && d[pn - 1][i][0] < minim)
      minim = d[pn - 1][i][0], pozmin = i;
  get_adn(pozmin, pn - 1);

  return 0;
}