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

#include <bits/stdc++.h>
using namespace std;
typedef vector<int> vi;
typedef vector<vi> vvi;
typedef vector<string> vs;
typedef pair<int, int> pii;
typedef long long ll;
#define ALL(a) (a).begin(), (a).end()
#define RALL(a) (a).rbegin(), (a).rend()
#define EXIST(s, e) ((s).find(e) != (s).end())
#define FOR(i, a, b) for (int i = (a); i < (b); ++i)
#define REP(i, n) FOR(i, 0, n)

vs dfs(vs &words, vs &c_words, map<char, char> &m, int cur, vs &orig_c_words) {
  vs ret;
  if (cur == orig_c_words.size()) {
    REP(i, orig_c_words.size()) {
      string s;
      REP(j, orig_c_words[i].size()) { s.push_back(m[orig_c_words[i][j]]); }
      ret.push_back(s);
    }
    return ret;
  }

  REP(i, words.size()) {
    if (words[i].size() == c_words[cur].size()) {
      map<char, char> nm(m);
      bool ok = true;
      REP(j, words[i].size()) {
        map<char, char>::iterator it_i = nm.find(words[i][j]);
        map<char, char>::iterator it_c = nm.find(c_words[cur][j]);
        bool ei = it_i != nm.end();
        bool ec = it_c != nm.end();
        if (ei && ec) {
          if (it_i->second != c_words[cur][j] || it_c->second != words[i][j]) {
            ok = false;
            break;
          }
        } else if (ei || ec) {
          ok = false;
          break;
        } else {
          nm[words[i][j]] = c_words[cur][j];
          nm[c_words[cur][j]] = words[i][j];
        }
      }
      if (ok) {
        // cerr<<"cur:"<<cur<<endl;
        vs res = dfs(words, c_words, nm, cur + 1, orig_c_words);
        // cerr<<"res:"<<res.size()<<endl;
        if (res.size() > 0) {
          if (res.size() == 100) {
            return vs(100);
          }
          if (ret.size()) {
            return vs(100);
          } else {
            ret = res;
          }
        }
      }
    }
  }
  return ret;
}
bool pred(const string &l, const string &r) {
  if (l.size() == r.size()) {
    return l > r;
  } else {
    return l.size() > r.size();
  }
}
int main() {
  int n;
  while (cin >> n, n) {
    vs words(n);
    REP(i, n) { cin >> words[i]; }
    string sequence;
    getline(cin, sequence);
    getline(cin, sequence);
    vs c_words;
    int prev = 0;
    REP(i, sequence.size()) {
      switch (sequence[i]) {
      case ' ':
      case '.':
        c_words.push_back(sequence.substr(prev, i - prev));
        prev = i + 1;
        break;
      }
    }
    vs orig_c_words(c_words);
    sort(ALL(c_words), pred);
    map<char, char> m;
    vs res = dfs(words, c_words, m, 0, orig_c_words);
    if (res.size() && res.size() < 100) {
      REP(i, res.size()) { cout << res[i] << (i < res.size() - 1 ? " " : ""); }
      cout << "." << endl;
    } else {
      cout << "-." << endl;
    }
  }
}

Error: TLE

Fixed submission:

#include <bits/stdc++.h>
using namespace std;
typedef vector<int> vi;
typedef vector<vi> vvi;
typedef vector<string> vs;
typedef pair<int, int> pii;
typedef long long ll;
#define ALL(a) (a).begin(), (a).end()
#define RALL(a) (a).rbegin(), (a).rend()
#define EXIST(s, e) ((s).find(e) != (s).end())
#define FOR(i, a, b) for (int i = (a); i < (b); ++i)
#define REP(i, n) FOR(i, 0, n)

vs dfs(vs &words, vs &c_words, map<char, char> &m, int cur, vs &orig_c_words) {
  vs ret;
  if (cur == orig_c_words.size()) {
    REP(i, orig_c_words.size()) {
      string s;
      REP(j, orig_c_words[i].size()) { s.push_back(m[orig_c_words[i][j]]); }
      ret.push_back(s);
    }
    return ret;
  }

  REP(i, words.size()) {
    if (words[i].size() == c_words[cur].size()) {
      map<char, char> nm(m);
      bool ok = true;
      REP(j, words[i].size()) {
        map<char, char>::iterator it_i = nm.find(words[i][j]);
        map<char, char>::iterator it_c = nm.find(c_words[cur][j]);
        bool ei = it_i != nm.end();
        bool ec = it_c != nm.end();
        if (ei && ec) {
          if (it_i->second != c_words[cur][j] || it_c->second != words[i][j]) {
            ok = false;
            break;
          }
        } else if (ei || ec) {
          ok = false;
          break;
        } else {
          nm[words[i][j]] = c_words[cur][j];
          nm[c_words[cur][j]] = words[i][j];
        }
      }
      if (ok) {
        // cerr<<"cur:"<<cur<<endl;
        vs res = dfs(words, c_words, nm, cur + 1, orig_c_words);
        // cerr<<"res:"<<res.size()<<endl;
        if (res.size()) {
          if (ret.size()) {
            return vs();
          } else {
            ret = res;
          }
        }
      }
    }
  }
  return ret;
}
bool pred(const string &l, const string &r) {
  if (l.size() == r.size()) {
    return l > r;
  } else {
    return l.size() > r.size();
  }
}
int main() {
  int n;
  while (cin >> n, n) {
    vs words(n);
    REP(i, n) { cin >> words[i]; }
    string sequence;
    getline(cin, sequence);
    getline(cin, sequence);
    vs c_words;
    int prev = 0;
    REP(i, sequence.size()) {
      switch (sequence[i]) {
      case ' ':
      case '.':
        c_words.push_back(sequence.substr(prev, i - prev));
        prev = i + 1;
        break;
      }
    }
    vs orig_c_words(c_words);
    sort(ALL(c_words), pred);
    map<char, char> m;
    vs res = dfs(words, c_words, m, 0, orig_c_words);
    if (res.size()) {
      REP(i, res.size()) { cout << res[i] << (i < res.size() - 1 ? " " : ""); }
      cout << "." << endl;
    } else {
      cout << "-." << endl;
    }
  }
}