Problem p01147 (C++) — buggy submission, verdict: Time Limit Exceeded

#include <algorithm>
#include <cmath>
#include <cstdio>
#include <cstring>
#include <deque>
#include <iostream>
#include <list>
#include <map>
#include <queue>
#include <set>
#include <sstream>
#include <stack>
#include <string>
#include <vector>
using namespace std;
bool operator>(const pair<string, int> &p, const pair<string, int> &q) {
  if (0) {
  } else if (p.second > q.second) {
    return 1;
  } else if (p.second == q.second) {
    if (p.first > q.first)
      return 1;
  }
  return 0;
}
int a[10], b[10][10], n;
string s[10];
pair<string, int> c[10][1 << 10];
pair<string, int> fi(int p, int q) {
  int i;
  if (c[p][q].second)
    return c[p][q];
  c[p][q].second = 1 << 30;
  for (i = 0; i < n; ++i) {
    if (q & (1 << i))
      continue;
    pair<string, int> t = fi(i, q | (1 << i));
    t.first = s[p].substr(0, a[p] - b[p][i]) + t.first;
    t.second += a[p] - b[p][i];
    if (c[p][q] > t)
      c[p][q] = t;
  }
  return c[p][q];
}
int main() {
  int i, j, k, l;
  while (cin >> n, n) {
    for (i = 0; i < n; ++i)
      cin >> s[i];
    for (i = 0; i < n - 1; ++i) {
      for (j = i + 1; j < n; ++j) {
        if (0) {
        } else if (s[i].find(s[j]) != string::npos) {
          copy(&s[j + 1], &s[n], &s[j]);
          --j;
          --n;
        } else if (s[j].find(s[i]) != string::npos) {
          copy(&s[i + 1], &s[n], &s[i]);
          --i;
          --n;
          break;
        }
      }
    }
    for (i = 0; i < n; ++i)
      a[i] = s[i].length();
    for (i = 0; i < n; ++i) {
      for (j = 0; j < n; ++j) {
        if (i == j)
          continue;
        for (k = max(1, a[i] - a[j] + 1); k < a[i]; ++k) {
          for (l = k; l < a[i]; ++l) {
            if (s[i][l] != s[j][l - k])
              break;
          }
          if (l == a[i])
            break;
        }
        b[i][j] = a[i] - k;
      }
    }
    fill(c[0], c[0] + 10 * (1 << 10), make_pair("", 0));
    for (i = 0; i < n; ++i)
      c[i][~(-1 << n)] = make_pair(s[i], a[i]);
    pair<string, int> mn = make_pair("", 1 << 30);
    for (i = 0; i < n; ++i) {
      pair<string, int> t = fi(i, 1 << i);
      if (mn > t)
        mn = t;
    }
    cout << mn.first << endl;
  }
  return 0;
}

Error: TLE

Fixed submission:

#include <algorithm>
#include <cmath>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <deque>
#include <iostream>
#include <list>
#include <map>
#include <queue>
#include <set>
#include <sstream>
#include <stack>
#include <string>
#include <vector>
using namespace std;
int n;
string s[10];
int ln[10];
int a[10][10], b[10];
pair<string, int> fn(int p, int q, pair<string, int> t) {
  int i;
  pair<string, int> u = make_pair("", 0);
  if (p == n) {
    u = t;
  } else {
    for (i = 0; i < n; i++) {
      if (b[i]) {
        b[i] = 0;
        pair<string, int> v =
            fn(p + 1, i,
               make_pair(t.first + s[i].substr(q < 0 ? 0 : a[q][i]),
                         t.second + ln[i] - (q < 0 ? 0 : a[q][i])));
        if (u.second == 0 || u.second > v.second ||
            (u.second == v.second && u.first > v.first))
          u = v;
        b[i] = -1;
      }
    }
  }
  return u;
}
int main() {
  int i, j, k, l;
  while (cin >> n && n) {
    memset(a, 0, sizeof(a));
    for (i = 0; i < n; i++) {
      cin >> s[i];
      ln[i] = s[i].length();
      for (j = 0; j < i; j++) {
        for (k = (ln[j] < ln[i] ? ln[i] - ln[j] : 0); k < ln[i]; k++) {
          for (l = 0; l < ln[i] - k; l++) {
            if (s[i][k + l] != s[j][l])
              break;
          }
          if (l == ln[i] - k) {
            a[i][j] = ln[i] - k;
            break;
          }
        }
        for (k = (ln[i] < ln[j] ? ln[j] - ln[i] : 0); k < ln[j]; k++) {
          for (l = 0; l < ln[j] - k; l++) {
            if (s[j][k + l] != s[i][l])
              break;
          }
          if (l == ln[j] - k) {
            a[j][i] = ln[j] - k;
            break;
          }
        }
        if (ln[i] == a[j][i] || ln[i] == a[i][j]) {
          i--;
          n--;
          break;
        }
      }
    }
    memset(b, -1, sizeof(b));
    cout << fn(0, -1, make_pair("", 0)).first << endl;
  }
  return 0;
}