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

#include "bits/stdc++.h"
using namespace std;

using VS = vector<string>;
using LL = long long;
using VI = vector<int>;
using VVI = vector<VI>;
using PII = pair<int, int>;
using PLL = pair<LL, LL>;
using VL = vector<LL>;
using VVL = vector<VL>;

#define ALL(a) begin((a)), end((a))
#define RALL(a) (a).rbegin(), (a).rend()
#define PB push_back
#define EB emplace_back
#define MP make_pair
#define SZ(a) int((a).size())
#define SORT(c) sort(ALL((c)))
#define RSORT(c) sort(RALL((c)))
#define UNIQ(c) (c).erase(unique(ALL((c))), end((c)))
#define FOR(i, s, e) for (int(i) = (s); (i) < (e); (i)++)
#define FORR(i, s, e) for (int(i) = (s); (i) > (e); (i)--)
#define debug(x) cerr << #x << ": " << x << endl
const int INF = 1e9;
const LL LINF = 1e16;
const LL MOD = 1000000007;
const double PI = acos(-1.0);
int DX[8] = {0, 0, 1, -1, 1, 1, -1, -1};
int DY[8] = {1, -1, 0, 0, 1, -1, 1, -1};

/* -----  2017/11/13  Problem: NU_27_A / Link: __CONTEST_URL__  ----- */
/* ------問題------



-----問題ここまで----- */
/* -----解説等-----



----解説ここまで---- */

void get_dist1(string &s, set<string> &a) {
  a.insert(s);
  FOR(i, 0, SZ(s)) { // delete
    a.insert(s.substr(0, i) + s.substr(i + 1));
  }
  FOR(i, 0, SZ(s) - 1) { // swap
    swap(s[i], s[i + 1]);
    a.insert(s);
    swap(s[i], s[i + 1]);
  }
  FOR(i, 0, SZ(s)) { // replace
    char c = s[i];
    FOR(j, 0, 26) {
      s[i] = 'a' + j;
      a.insert(s);
    }
    s[i] = c;
  }
  // insert
  FOR(i, 0, 26) a.insert(s + (char)('a' + i));
  FOR(i, 0, SZ(s)) {
    FOR(j, 0, 26)
    a.insert(s.substr(0, i) + (char)('a' + j) + s.substr(i));
  }
}

void gen_set(string s, set<string> &d) {
  d.clear();

  // delete
  for (int i = 0; i < s.length(); i++) {
    string tmp;
    for (int j = 0; j < s.length(); j++)
      if (i != j)
        tmp += s[j];
    d.insert(tmp);
  }

  // insert
  for (int i = 0; i <= s.length(); i++) {
    for (char c = 'a'; c <= 'z'; c++) {
      string tmp;
      for (int j = 0; j < s.length(); j++) {
        if (i == j)
          tmp += c;
        tmp += s[j];
      }
      if (i == s.length())
        tmp += c;
      d.insert(tmp);
    }
  }

  // replace
  for (int i = 0; i < s.length(); i++) {
    for (char c = 'a'; c <= 'z'; c++) {
      string tmp = s;
      tmp[i] = c;
      d.insert(tmp);
    }
  }
  // FOR(i, 0, SZ(s)) {//swap
  //	FOR(j, i + 1, SZ(s)) {
  //		swap(s[i], s[j]);
  //		d.insert(s);
  //		swap(s[j], s[i]);
  //	}
  // }

  // swap
  for (int i = 0; i < s.length() - 1; i++) {
    string tmp = s;
    swap(tmp[i], tmp[i + 1]);
    d.insert(tmp);
  }

  d.insert(s);
}
// int matching2(string&s, string&t) {
//	/* edit dist <=1を作成 */
//	set<string>a(get_dist1(s));
//	set<string>b(get_dist1(t));
//	for (string s : a)if(b.find(s)!=b.end())return true;
//	return false;
// }
// int matching2(string&s, string&t) {
//	/* edit dist <=1を作成 */
//	set<string>a(get_dist1(s));
//	int SZA = SZ(a);
//	set<string>b(get_dist1(t));
//	int SZB = SZ(b);
//	for (string s : a)b.insert(s);
//	int SZM = SZ(b);
//	if (SZM == SZB + SZA)return false;
//	else return true;
// }
// int matching1(string&s, string&t) {
//	/* edit dist <=1を作成 */
//	set<string>b(get_dist1(s));
//	set<string>a; a.insert(t);
//	int SZB = SZ(b);
//	int SZA = SZ(a);
//	for (string ss : a)b.insert(ss);
//	int SZM = SZ(b);
//	if (SZM == SZB + SZA)return false;
//	else return true;
// }

int matching(int i, int j, int d, const VS &vs,
             const vector<set<string>> &vseset) {
  /* edit dist <=1を作成 */
  if (d == 1) {
    if (vseset[i].find(vs[j]) != vseset[i].end())
      return true;
    else
      return false;
  } else {
    if (vseset[i].size() < vseset[j].size())
      swap(i, j);
    for (string s : vseset[j]) {
      if (vseset[i].find(s) != vseset[i].end())
        return true;
    }
    return false;
  }
}
// int matching(string &s, string &t, int d) {
//	return (d == 1 ? matching1(s, t) : matching2(s, t));
// }
int N;
int dp[17][17];
//
// int func_dp(string&s, string&t, int d) {
//	int SZ_S = SZ(s);
//	int SZ_T = SZ(t);
//	fill(*dp, *dp + 17 * 17, 100);
//	// 0はまだどれもswapしてない
//	/*VVI ruis(SZ_S + 1, VI(26, 0));
//	VVI ruit(SZ_T + 1, VI(26, 0));*/
//	FOR(i, 0, SZ_S + 1) {
//		dp[i][0] = i;
//	}
//	FOR(j, 0, SZ_T + 1) {
//		dp[0][j] = j;
//	}
//	/*FOR(i, 0, SZ_S) {
//		FOR(j, 0, 26)
//			ruis[i + 1][j] += ruis[i][j] + (s[i] == ('a' + j) ? 1 :
//0);
//	}
//	FOR(i, 0, SZ_T) {
//		FOR(j, 0, 26)
//			ruis[i + 1][j] += ruis[i][j] + (t[i] == ('a' + j) ? 1 :
//0);
//	}*/
//	int INDEX_T = 0;
//	int c = 0;
//	FOR(i, 1, SZ_S + 1) {
//		FOR(j, 1, SZ_T + 1) {
//			if (s[i] != t[j])c = 1;
//			else c = 0;
//			dp[i][j] = min(dp[i][j], dp[i - 1][j - 1] + c);
//			dp[i][j] = min(dp[i][j], dp[i - 1][j] + c);
//			dp[i][j] = min(dp[i][j], dp[i][j - 1] + c);
//		}
//	}
//	FOR(k, 0, 26) {
//		if (dp[SZ_S][SZ_T] <= d)return 1;
//	}
//	return 0;
//}

int main() {
  cin.tie(0);
  ios_base::sync_with_stdio(false);
  while (cin >> N, N) {
    int d;
    cin >> d;
    VS orig(N);
    string ss;
    vector<set<string>> vseset(N, set<string>());
    FOR(i, 0, N) {
      cin >> orig[i];
      // get_dist1(orig[i], vseset[i]);
      get_dist1(orig[i], vseset[i]);
    }
    vector<pair<string, string>> se;
    FOR(i, 0, N) {
      FOR(j, i + 1, N) {
        if (matching(i, j, d, orig, vseset)) {
          if (orig[i] < orig[j])
            se.push_back(pair<string, string>(orig[i], orig[j]));
          else
            se.push_back(pair<string, string>(orig[j], orig[i]));
        }
      }
    }

    int ans = SZ(se);
    SORT(se);
    FOR(i, 0, ans) { cout << se[i].first << "," << se[i].second << endl; }
    cout << ans << endl;
  }
  // printf("%s\\n", str);

  return 0;
}

Error: TLE

Fixed submission:

#include "bits/stdc++.h"
using namespace std;
typedef long long ll;
typedef pair<int, int> pii;
typedef pair<ll, ll> pll;
#define INF 1 << 30
#define LINF 1LL << 60

int calc(const string &s1, const string &s2) {
  vector<vector<int>> dp(s1.length() + 1, vector<int>(s2.length() + 1, INF));

  /* dp[i][j] := 文字列s1[0..(i-1)] から 文字列s2[0..(j-1)]の編集距離 (
   * 添え字0はヌル ) */
  dp[0][0] = 0;
  for (int i = 1; i <= s1.length(); i++)
    dp[i][0] = i;
  for (int j = 1; j <= s2.length(); j++)
    dp[0][j] = j;

  for (int i = 1; i <= s1.length(); i++) {
    for (int j = 1; j <= s2.length(); j++) {
      dp[i][j] = min({dp[i][j - 1] + 1, dp[i - 1][j] + 1,
                      dp[i - 1][j - 1] + (s1[i - 1] != s2[j - 1])});
    }
  }

  return dp[s1.length()][s2.length()];
}

int main(void) {
  cin.tie(0);
  ios::sync_with_stdio(false);
  ll n, d;
  set<pair<int, int>> s;
  vector<string> name;
  while (cin >> n, n) {
    cin >> d;
    s.clear();
    name.clear();
    name.resize(n);
    for (int i = 0; i < n; i++) {
      cin >> name[i];
    }
    sort(name.begin(), name.end());
    for (int i = 0; i < n; i++) {
      for (int j = 0; j < n; j++) {
        if (i == j)
          continue;
        int dist = calc(name[i], name[j]);
        if (dist <= d) {
          if (i < j) {
            s.insert({i, j});
          } else {
            s.insert({j, i});
          }
          continue;
        }
        string tmp;
        bool f = false;
        for (int k = 0; k < name[i].length() - 1; k++) {
          for (int l = 0; l < name[i].length() - 1; l++) {
            tmp = name[i];
            int cost = 1;
            swap(tmp[k], tmp[k + 1]);
            if (k != l) {
              swap(tmp[l], tmp[l + 1]);
              cost++;
            }
            dist = calc(tmp, name[j]) + cost;
            if (dist <= d) {
              if (i < j) {
                s.insert({i, j});
              } else {
                s.insert({j, i});
              }
              f = true;
              break;
            }
          }
          if (f)
            break;
        }
      }
    }
    for (auto pii : s) {
      cout << name[pii.first] << "," << name[pii.second] << endl;
    }
    cout << s.size() << endl;
  }
  return 0;
}