Problem p00608 (C++)

Buggy submission (status: Runtime Error):
#include <algorithm>
#include <cassert>
#include <cctype>
#include <cstdint>
#include <cstdio>
#include <string>
#include <vector>

constexpr int tsurai = 123456789;

int parse_int(const std::string &s, size_t &i) {
  assert(isdigit(s[i]));
  int res = s[i] - '0';
  while (++i < s.length() && isdigit(s[i])) {
    res = res * 10 + s[i] - '0';
  }
  return res;
}

int fourt(const std::string &s, size_t &i) {
  int res = 0;
  char sgn = '+';
  while (i < s.length() && isdigit(s[i])) {
    int cur = parse_int(s, i);
    while (i < s.length() && s[i] != '=') {
      if (s[i] == '*') {
        cur *= parse_int(s, ++i);
      } else if (s[i] == '/') {
        int tmp = parse_int(s, ++i);
        if (tmp == 0 || cur % tmp)
          return tsurai;
        cur /= tmp;
      } else {
        break;
      }
    }
    if (sgn == '+') {
      res += cur;
    } else {
      res -= cur;
    }
    if (i < s.length() && s[i] != '=') {
      sgn = s[i++];
    }
  }
  return res;
}

bool valid(const std::vector<std::string> &eqs, const std::vector<char> &cs) {
  for (/* not const */ std::string eq : eqs) {
    for (char &ch : eq)
      if (ch >= 'A' && ch <= 'Z')
        ch = cs[ch - 'A'];

    if (eq[0] == '=' || eq.back() == '=')
      return false;
    if (std::count(eq.begin(), eq.end(), '=') != 1)
      return false;

    for (size_t i = 0; i + 1 < eq.length(); ++i) {
      if (isdigit(eq[i]))
        continue;
      if (!isdigit(eq[i + 1]))
        return false;
    }

    for (size_t i = 0; i < eq.length(); ++i) {
      if (!isdigit(eq[i]))
        continue;
      if (eq[i] != '0') {
        do {
          ++i;
        } while (i < eq.length() && isdigit(eq[i]));
      } else {
        if (i + 1 < eq.length() && isdigit(eq[i + 1]))
          return false;
      }
    }

    size_t i = 0;
    if (!isdigit(eq[i]))
      return false;
    int lhs = fourt(eq, i);
    if (lhs == tsurai)
      return false;
    assert(eq[i] == '=');
    ++i;
    if (!isdigit(eq[i]))
      return false;
    int rhs = fourt(eq, i);
    if (rhs == tsurai)
      return false;
    assert(i == eq.length());

    if (lhs != rhs)
      return false;
  }
  return true;
}

int testcase_ends() {
  size_t H, W;
  scanf("%zu %zu", &H, &W);

  if (H == 0 && W == 0)
    return 1;

  size_t ph = 'A'; // placeholder
  std::vector<std::string> s(H);
  for (size_t i = 0; i < H; ++i) {
    char buf[16];
    scanf("%s", buf);
    s[i] = buf;
    for (size_t j = 0; j < W; ++j) {
      if (s[i][j] == '.')
        s[i][j] = ph++;
    }
  }

  std::vector<std::string> eqs;
  for (size_t i = 0; i < H; ++i) {
    std::string eq = "";
    for (size_t j = 0; j < W; ++j) {
      if (s[i][j] != '#') {
        eq += s[i][j];
      } else {
        if (eq.size() >= 3)
          eqs.emplace_back(eq);
        eq = "";
      }
    }
    if (eq.size() >= 3)
      eqs.emplace_back(eq);
  }

  for (size_t j = 0; j < W; ++j) {
    std::string eq = "";
    for (size_t i = 0; i < H; ++i) {
      if (s[i][j] != '#') {
        eq += s[i][j];
      } else {
        if (eq.size() >= 3)
          eqs.emplace_back(eq);
        eq = "";
      }
    }
    if (eq.size() >= 3)
      eqs.emplace_back(eq);
  }

  size_t n;
  scanf("%zu", &n);
  std::vector<char> cs(n);
  for (size_t i = 0; i < n; ++i)
    scanf(" %c", &cs[i]);

  std::sort(cs.begin(), cs.end());
  do {
    if (valid(eqs, cs))
      return !printf("Yes\n");
  } while (std::next_permutation(cs.begin(), cs.end()));
  printf("No\n");
  return 0;
}

int main() {
  while (!testcase_ends()) {
  }
}


Fixed submission:
#include <algorithm>
#include <cassert>
#include <cctype>
#include <cstdint>
#include <cstdio>
#include <string>
#include <vector>

constexpr int tsurai = 123456789;

int parse_int(const std::string &s, size_t &i) {
  assert(isdigit(s[i]));
  int res = s[i] - '0';
  while (++i < s.length() && isdigit(s[i])) {
    res = res * 10 + s[i] - '0';
  }
  return res;
}

int fourt(const std::string &s, size_t &i) {
  int res = 0;
  char sgn = '+';
  while (i < s.length() && isdigit(s[i])) {
    int cur = parse_int(s, i);
    while (i < s.length() && s[i] != '=') {
      if (s[i] == '*') {
        cur *= parse_int(s, ++i);
      } else if (s[i] == '/') {
        int tmp = parse_int(s, ++i);
        if (tmp == 0 || cur % tmp)
          return tsurai;
        cur /= tmp;
      } else {
        break;
      }
    }
    if (sgn == '+') {
      res += cur;
    } else {
      res -= cur;
    }
    if (i < s.length() && s[i] != '=') {
      sgn = s[i++];
    }
  }
  return res;
}

bool valid(const std::vector<std::string> &eqs, const std::vector<char> &cs) {
  for (/* not const */ std::string eq : eqs) {
    for (char &ch : eq)
      if (ch >= 'A' && ch <= 'Z')
        ch = cs[ch - 'A'];

    if (eq[0] == '=' || !isdigit(eq.back()))
      return false;
    if (std::count(eq.begin(), eq.end(), '=') != 1)
      return false;

    for (size_t i = 0; i + 1 < eq.length(); ++i) {
      if (isdigit(eq[i]))
        continue;
      if (!isdigit(eq[i + 1]))
        return false;
    }

    for (size_t i = 0; i < eq.length(); ++i) {
      if (!isdigit(eq[i]))
        continue;
      if (eq[i] != '0') {
        do {
          ++i;
        } while (i < eq.length() && isdigit(eq[i]));
      } else {
        if (i + 1 < eq.length() && isdigit(eq[i + 1]))
          return false;
      }
    }

    size_t i = 0;
    if (!isdigit(eq[i]))
      return false;
    int lhs = fourt(eq, i);
    if (lhs == tsurai)
      return false;
    assert(eq[i] == '=');
    ++i;
    if (!isdigit(eq[i]))
      return false;
    int rhs = fourt(eq, i);
    if (rhs == tsurai)
      return false;
    assert(i == eq.length());

    if (lhs != rhs)
      return false;
  }
  return true;
}

int testcase_ends() {
  size_t H, W;
  scanf("%zu %zu", &H, &W);

  if (H == 0 && W == 0)
    return 1;

  size_t ph = 'A'; // placeholder
  std::vector<std::string> s(H);
  for (size_t i = 0; i < H; ++i) {
    char buf[16];
    scanf("%s", buf);
    s[i] = buf;
    for (size_t j = 0; j < W; ++j) {
      if (s[i][j] == '.')
        s[i][j] = ph++;
    }
  }

  std::vector<std::string> eqs;
  for (size_t i = 0; i < H; ++i) {
    std::string eq = "";
    for (size_t j = 0; j < W; ++j) {
      if (s[i][j] != '#') {
        eq += s[i][j];
      } else {
        if (eq.size() >= 3)
          eqs.emplace_back(eq);
        eq = "";
      }
    }
    if (eq.size() >= 3)
      eqs.emplace_back(eq);
  }

  for (size_t j = 0; j < W; ++j) {
    std::string eq = "";
    for (size_t i = 0; i < H; ++i) {
      if (s[i][j] != '#') {
        eq += s[i][j];
      } else {
        if (eq.size() >= 3)
          eqs.emplace_back(eq);
        eq = "";
      }
    }
    if (eq.size() >= 3)
      eqs.emplace_back(eq);
  }

  size_t n;
  scanf("%zu", &n);
  std::vector<char> cs(n);
  for (size_t i = 0; i < n; ++i)
    scanf(" %c", &cs[i]);

  std::sort(cs.begin(), cs.end());
  do {
    if (valid(eqs, cs))
      return !printf("Yes\n");
  } while (std::next_permutation(cs.begin(), cs.end()));
  printf("No\n");
  return 0;
}

int main() {
  while (!testcase_ends()) {
  }
}