Problem p00608 (C++)

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

#define fprintf(...) (void)0

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

int parse(std::string &s, size_t &i, bool &succ) {
  if (i == s.length()) {
    succ = false;
    return -1;
  }

  if (s[i] == '+' || s[i] == '-') {
    succ = false;
    return -1;
  }

  int res = 0;
  char sgn = '+';
  while (i < s.length()) {
    assert(isdigit(s[i]));

    int cur = parse_int(s, i);
    while (true) {
      if (s[i] == '*') {
        cur *= parse_int(s, ++i);
      } else if (s[i] == '/') {
        int tmp = parse_int(s, ++i);
        if (cur % tmp != 0) {
          succ = false;
          return -1;
        }
        cur /= tmp;
      } else {
        break;
      }
    }

    if (sgn == '+') {
      res += cur;
    } else if (sgn == '-') {
      res -= cur;
    }

    if (i == s.length() || s[i] == '=')
      return res;

    sgn = s[i++];
  }
  return res;
}

bool solved(const std::vector<std::string> &eqs, const std::vector<char> &ch) {
  fprintf(stderr, ": ");
  for (size_t i = 0; i < ch.size(); ++i)
    fprintf(stderr, "%c%c", ch[i], i + 1 < ch.size() ? ' ' : '\n');

  for (auto eq : eqs) {
    size_t i = 0;

    for (char &c : eq)
      if (c >= 'A' && c <= 'Z')
        c = ch[c - 'A'];

    fprintf(stderr, "# %s\n", eq.c_str());

    if (eq[0] == '=' || eq.back() == '=')
      return false;
    if (!isdigit(eq[0]) || !isdigit(eq.back()))
      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') {
        if (i + 1 < eq.length() && isdigit(eq[i + 1]))
          return false;
      }
      while (i + 1 < eq.length() && isdigit(eq[i + 1])) {
        ++i;
      }
    }

    if (std::count(eq.begin(), eq.end(), '=') != 1)
      return false;

    bool succ = true;
    int lhs = parse(eq, i, succ);
    if (!succ)
      return false;
    assert(eq[i] == '=');
    ++i;
    succ = true;
    int rhs = parse(eq, i, succ);
    if (!succ)
      return false;

    fprintf(stderr, "%s: %d %d\n", eq.c_str(), lhs, rhs);

    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;

  std::vector<std::string> g(H);
  for (size_t i = 0; i < H; ++i) {
    char buf[16];
    scanf("%s", buf);
    g[i] = buf;
  }

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

  char ph = 'A';
  for (size_t i = 0; i < H; ++i)
    for (size_t j = 0; j < W; ++j)
      if (g[i][j] == '.')
        g[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 (g[i][j] == '#') {
        if (eq.size() >= 3) {
          eqs.emplace_back(eq);
        }
        eq = "";
        continue;
      }

      eq += g[i][j];
    }
    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 (g[i][j] == '#') {
        if (eq.size() >= 3) {
          eqs.emplace_back(eq);
        }
        eq = "";
        continue;
      }

      eq += g[i][j];
    }
    if (eq.size() >= 3)
      eqs.emplace_back(eq);
  }

  std::sort(ch.begin(), ch.end());
  do {
    if (solved(eqs, ch)) {
      printf("Yes\n");
      return 0;
    }
  } while (std::next_permutation(ch.begin(), ch.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>

#define fprintf(...) (void)0

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

int parse(std::string &s, size_t &i, bool &succ) {
  if (i == s.length()) {
    succ = false;
    return -1;
  }

  if (s[i] == '+' || s[i] == '-') {
    succ = false;
    return -1;
  }

  int res = 0;
  char sgn = '+';
  while (i < s.length()) {
    assert(isdigit(s[i]));

    int cur = parse_int(s, i);
    while (true) {
      if (s[i] == '*') {
        cur *= parse_int(s, ++i);
      } else if (s[i] == '/') {
        int tmp = parse_int(s, ++i);
        if (tmp == 0 || cur % tmp != 0) {
          succ = false;
          return -1;
        }
        cur /= tmp;
      } else {
        break;
      }
    }

    if (sgn == '+') {
      res += cur;
    } else if (sgn == '-') {
      res -= cur;
    }

    if (i == s.length() || s[i] == '=')
      return res;

    sgn = s[i++];
  }
  return res;
}

bool solved(const std::vector<std::string> &eqs, const std::vector<char> &ch) {
  fprintf(stderr, ": ");
  for (size_t i = 0; i < ch.size(); ++i)
    fprintf(stderr, "%c%c", ch[i], i + 1 < ch.size() ? ' ' : '\n');

  for (auto eq : eqs) {
    size_t i = 0;

    for (char &c : eq)
      if (c >= 'A' && c <= 'Z')
        c = ch[c - 'A'];

    fprintf(stderr, "# %s\n", eq.c_str());

    if (eq[0] == '=' || eq.back() == '=')
      return false;
    if (!isdigit(eq[0]) || !isdigit(eq.back()))
      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') {
        if (i + 1 < eq.length() && isdigit(eq[i + 1]))
          return false;
      }
      while (i + 1 < eq.length() && isdigit(eq[i + 1])) {
        ++i;
      }
    }

    if (std::count(eq.begin(), eq.end(), '=') != 1)
      return false;

    bool succ = true;
    int lhs = parse(eq, i, succ);
    if (!succ)
      return false;
    assert(eq[i] == '=');
    ++i;
    succ = true;
    int rhs = parse(eq, i, succ);
    if (!succ)
      return false;

    fprintf(stderr, "%s: %d %d\n", eq.c_str(), lhs, rhs);

    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;

  std::vector<std::string> g(H);
  for (size_t i = 0; i < H; ++i) {
    char buf[16];
    scanf("%s", buf);
    g[i] = buf;
  }

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

  char ph = 'A';
  for (size_t i = 0; i < H; ++i)
    for (size_t j = 0; j < W; ++j)
      if (g[i][j] == '.')
        g[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 (g[i][j] == '#') {
        if (eq.size() >= 3) {
          eqs.emplace_back(eq);
        }
        eq = "";
        continue;
      }

      eq += g[i][j];
    }
    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 (g[i][j] == '#') {
        if (eq.size() >= 3) {
          eqs.emplace_back(eq);
        }
        eq = "";
        continue;
      }

      eq += g[i][j];
    }
    if (eq.size() >= 3)
      eqs.emplace_back(eq);
  }

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

  printf("No\n");
  return 0;
}

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