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

#pragma GCC optimize "O3"

#include <bits/stdc++.h>

using namespace std;

constexpr int N = 20;

int n, ans;
string tmp, ans_rev;
vector<string> words[N + 1], cands[N + 1];

inline bool valid(string &tar, string &s, string &rev) {
  for (size_t i = 0; i < s.size(); ++i) {
    if (rev[s[i]] != -1 && rev[s[i]] != tar[i])
      return false;
    if (rev[tar[i]] != -1 && rev[tar[i]] != s[i])
      return false;
  }
  return true;
}
void dfs(int l, size_t x, string &rev) {
  if (ans > 1)
    return;
  while (l && x >= words[l].size()) {
    x = 0;
    --l;
  }
  if (l == 0) {
    ans_rev = rev;
    ++ans;
    return;
  }
  string &tar = words[l][x];
  for (size_t j = 0; j < cands[l].size(); ++j) {
    string &s = cands[l][j];
    if (valid(tar, s, rev)) {
      string nrev = rev;
      size_t i = 0;
      for (; i < s.size(); ++i)
        if (nrev[s[i]] == -1) {
          if (nrev[tar[i]] != -1)
            break;
          nrev[s[i]] = tar[i];
          nrev[tar[i]] = s[i];
        }
      if (i != s.size())
        continue;
      dfs(l, x + 1, nrev);
    }
  }
}
void cleanup(vector<string> &v) {
  sort(v.begin(), v.end());
  v.resize(unique(v.begin(), v.end()) - v.begin());
}
void init() {
  for (int i = 0; i <= N; ++i)
    words[i].clear(), cands[i].clear();
  ans = 0;
}
void solve() {
  init();
  for (int i = 0; i < n; ++i) {
    cin >> tmp;
    for_each(tmp.begin(), tmp.end(), [](char &c) { c -= 'A'; });
    cands[tmp.size()].push_back(tmp);
  }
  vector<string> sent;
  bool cont = true;
  while (cont) {
    cin >> tmp;
    if (tmp.back() == '.') {
      tmp.pop_back();
      cont = false;
    }
    sent.push_back(tmp);
    for_each(tmp.begin(), tmp.end(), [](char &c) { c -= 'A'; });
    words[tmp.size()].push_back(tmp);
  }
  for (int i = 1; i <= N; ++i)
    cleanup(words[i]);
  string rev(26, -1);
  dfs(N, 0, rev);
  if (ans == 1) {
    for (size_t i = 0; i < sent.size(); ++i) {
      for (auto c : sent[i])
        putchar(ans_rev[c - 'A'] == -1 ? c : ans_rev[c - 'A'] + 'A');
      putchar(i + 1 == sent.size() ? '.' : ' ');
    }
    puts("");
  } else
    puts("-.");
}
int main() {
  while (scanf("%d", &n) == 1 && n)
    solve();
}

Error: TLE

Fixed submission:

#pragma GCC optimize "O3"

#include <bits/stdc++.h>

using namespace std;

constexpr int N = 20;

int n, ans;
string tmp, ans_rev;
vector<string> words[N + 1], cands[N + 1];

bool valid(string &tar, string &s, string &rev) {
  assert(tar.size() == s.size());
  for (size_t i = 0; i < s.size(); ++i) {
    if (rev[s[i]] != -1 && rev[s[i]] != tar[i])
      return false;
    if (rev[tar[i]] != -1 && rev[tar[i]] != s[i])
      return false;
  }
  return true;
}
void dfs(int l, size_t x, string &rev) {
  while (l && x >= words[l].size()) {
    x = 0;
    --l;
  }
  if (l == 0) {
    ans_rev = rev;
    // for(auto c : ans_rev)
    //   cerr << char(c + 'A');
    // cerr << endl;
    ++ans;
    return;
  }
  string &tar = words[l][x];
  for (auto &s : cands[l])
    if (valid(tar, s, rev)) {
      string nrev = rev;
      size_t i = 0;
      for (; i < s.size(); ++i)
        if (nrev[s[i]] == -1) {
          if (nrev[tar[i]] != -1)
            break;
          nrev[s[i]] = tar[i];
          nrev[tar[i]] = s[i];
        }
      if (i != s.size())
        continue;
      dfs(l, x + 1, nrev);
    }
}
void cleanup(vector<string> &v) {
  sort(v.begin(), v.end());
  v.resize(unique(v.begin(), v.end()) - v.begin());
}
void init() {
  for (int i = 0; i <= N; ++i)
    words[i].clear(), cands[i].clear();
  ans = 0;
}
void solve() {
  init();
  for (int i = 0; i < n; ++i) {
    cin >> tmp;
    for_each(tmp.begin(), tmp.end(), [](char &c) { c -= 'A'; });
    cands[tmp.size()].push_back(tmp);
  }
  vector<string> sent;
  bool cont = true;
  while (cont) {
    cin >> tmp;
    if (tmp.back() == '.') {
      tmp.pop_back();
      cont = false;
    }
    sent.push_back(tmp);
    for_each(tmp.begin(), tmp.end(), [](char &c) { c -= 'A'; });
    words[tmp.size()].push_back(tmp);
  }
  for (int i = 1; i <= N; ++i)
    cleanup(words[i]);
  string rev(26, -1);
  dfs(N, 0, rev);
  if (ans == 1) {
    for (size_t i = 0; i < sent.size(); ++i) {
      for (auto c : sent[i])
        putchar(ans_rev[c - 'A'] == -1 ? c : ans_rev[c - 'A'] + 'A');
      putchar(i + 1 == sent.size() ? '.' : ' ');
    }
    puts("");
  } else
    puts("-.");
}
int main() {
  while (scanf("%d", &n) == 1 && n)
    solve();
}