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

#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];
// vector<bool> vis[N+1];

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) {
    // if(vis[l][j])
    //   continue;
    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;
      // vis[l][j] = true;
      dfs(l, x + 1, nrev);
      // vis[l][j] = false;
    }
  }
}
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(); //, vis[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);
  }
  // for(int i = 0; i<=N; ++i)
  //   vis[i].resize(cands[i].size());
  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 = 0; i <= N; ++i)
    cleanup(words[i]);
  string rev(26, -1);
  dfs(N, 0, rev);
  if (ans == 1) {
    for (auto c : ans_rev)
      if (c != -1) {
        assert(c == ans_rev[ans_rev[c]]);
      }
    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: -6
3411d5f4-dc56-4417-adba-9ad2b0c6a8c5.out: /home/alex/Documents/bug-detection/input/Project_CodeNet/data/p00896/C++/s358176107.cpp:95: void solve(): Assertion `c == ans_rev[ans_rev[c]]' failed.


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];
// vector<bool> vis[N+1];

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) {
    // if(vis[l][j])
    //   continue;
    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;
      // vis[l][j] = true;
      dfs(l, x + 1, nrev);
      // vis[l][j] = false;
    }
  }
}
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(); //, vis[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);
  }
  // for(int i = 0; i<=N; ++i)
  //   vis[i].resize(cands[i].size());
  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 = 0; i <= N; ++i)
    cleanup(words[i]);
  string rev(26, -1);
  dfs(N, 0, rev);
  if (ans == 1) {
    for (auto c : ans_rev)
      if (ans_rev[c] != -1)
        assert(c == ans_rev[ans_rev[c]]);
    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();
}