Problem p01147 (C++) — buggy submission, verdict: Runtime Error

#include <algorithm>
#include <cctype>
#include <cmath>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <iostream>
#include <map>
#include <numeric>
#include <queue>
#include <set>
#include <sstream>
#include <stack>
#include <string>
#include <tuple>
#include <vector>

#ifdef _MSC_VER
#include <agents.h>
#endif

#define FOR(i, a, b) for (int i = (a); i < (int)(b); ++i)
#define rep(i, n) FOR(i, 0, n)
#define ALL(v) v.begin(), v.end()
#define REV(v) v.rbegin(), v.rend()
#define MEMSET(v, s) memset(v, s, sizeof(v))
#define X first
#define Y second

using namespace std;

typedef long long ll;
typedef pair<int, int> P;

vector<string> words;
int x[15][15];

string dp[1 << 10][10];
const string INF = string(200, 'z');

int samecnt(const string &a, const string &b) {
  rep(i, a.size()) {
    bool ok = true;
    FOR(j, i, a.size()) {
      if (j - i >= b.size() || a[j] != b[j - i]) {
        ok = false;
        break;
      }
    }
    if (ok)
      return a.size() - i;
  }
  return 0;
}

int n;
string rec(int bits, int pos) {
  if (bits + 1 == (1 << n)) {
    return words[pos];
  }

  string &res = dp[bits][pos];
  if (res != INF)
    return res;

  rep(i, n) {
    if (bits & (1 << i))
      continue;
    string ret = words[pos];
    string ret2 = rec(bits | (1 << i), i);
    ret += ret2.substr(x[pos][i]);
    if (res.size() < ret.size())
      continue;
    if (res.size() > ret.size())
      res = ret;
    else
      res = min(res, ret);
  }

  return res;
}

int main() {
  // cout << INF << endl;
  while (cin >> n, n) {
    words.clear();
    words.resize(n);
    rep(i, n) cin >> words[i];
    int e = 0;
    sort(ALL(words));
    words.erase(unique(ALL(words)), words.end());
    n = words.size();
    rep(i, n) rep(j, n) {
      if (words[i] == string(200, 'z'))
        continue;
      if (i == j)
        continue;
      if (words[i].find(words[j]) != -1)
        words[j] = string(200, 'z'), ++e;
    }
    sort(ALL(words));
    n -= e;
    rep(i, n) rep(j, n) {
      if (i == j)
        continue;
      // cout << words[i] << " " << words[j] << endl;
      // cout << samecnt(words[i], words[j]) << endl;
      x[i][j] = samecnt(words[i], words[j]);
    }
    rep(i, n) rep(j, 1 << n) dp[j][i] = INF;
    string ans = INF;
    rep(i, n) {
      string ret = rec(1 << i, i);
      if (ans.size() > ret.size() || (ans.size() == ret.size() && ret < ans)) {
        ans = ret;
      }
    }
    cout << ans << endl;
  }

  return 0;
}

Error: 0

Fixed submission:

#include <algorithm>
#include <cctype>
#include <cmath>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <iostream>
#include <map>
#include <numeric>
#include <queue>
#include <set>
#include <sstream>
#include <stack>
#include <string>
#include <tuple>
#include <vector>

#ifdef _MSC_VER
#include <agents.h>
#endif

#define FOR(i, a, b) for (int i = (a); i < (int)(b); ++i)
#define rep(i, n) FOR(i, 0, n)
#define ALL(v) v.begin(), v.end()
#define REV(v) v.rbegin(), v.rend()
#define MEMSET(v, s) memset(v, s, sizeof(v))
#define X first
#define Y second

using namespace std;

typedef long long ll;
typedef pair<int, int> P;

string words[10];
int x[15][15];

int dp[1 << 10][10];
int nxt[1 << 10][10];

int samecnt(const string &a, const string &b) {
  rep(i, a.size()) {
    bool ok = true;
    FOR(j, i, a.size()) {
      if (j - i >= b.size() || a[j] != b[j - i]) {
        ok = false;
        break;
      }
    }
    if (ok)
      return a.size() - i;
  }
  return 0;
}

int n;
int rec(int bits, int pos) {
  if (bits + 1 == (1 << n)) {
    return 0;
  }

  int &res = dp[bits][pos];
  if (res >= 0)
    return res;

  res = 0;
  rep(i, n) {
    if (bits & (1 << i))
      continue;
    int ret = rec(bits | (1 << i), i) + x[pos][i];
    if (res < ret) {
      res = ret;
      nxt[bits][pos] = i;
    }
  }

  return res;
}

void restore(int bits, int p, vector<int> &res) {
  int x = nxt[bits][p];
  res.push_back(p);
  if (x < 0)
    return;
  restore(bits | (1 << x), x, res);
}

int main() {
  while (cin >> n, n) {
    rep(i, n) cin >> words[i];
    sort(words, words + n);
    rep(i, n) rep(j, n) {
      if (i == j)
        continue;
      // cout << words[i] << " " << words[j] << endl;
      // cout << samecnt(words[i], words[j]) << endl;
      x[i][j] = samecnt(words[i], words[j]);
    }
    MEMSET(dp, -1);
    MEMSET(nxt, -1);
    int ans = -1, start = -1;
    rep(i, n) {
      int ret = rec(1 << i, i);
      if (ans < ret) {
        ans = ret;
        start = i;
      }
    }
    vector<int> seq;
    restore((1 << start), start, seq);
    rep(i, n) {
      if (i)
        cout << words[seq[i]].substr(x[seq[i - 1]][seq[i]]);
      else
        cout << words[seq[i]];
    }
    cout << endl;
  }

  return 0;
}