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

#include <bits/stdc++.h>
using namespace std;
#define FOR(i, k, n) for (int i = (k); i < (n); i++)
#define REP(i, n) FOR(i, 0, n)
#define ALL(a) a.begin(), a.end()
#define MS(m, v) memset(m, v, sizeof(m))
#define D10 fixed << setprecision(10)
typedef long long ll;
typedef long double ld;
typedef vector<int> vi;
typedef vector<string> vs;
typedef pair<int, int> pii;
const int MOD = 1000000007;
const int INF = MOD + 1;
const ld EPS = 1e-12;
template <class T> T &chmin(T &a, const T &b) { return a = min(a, b); }
template <class T> T &chmax(T &a, const T &b) { return a = max(a, b); }

/*--------------------template--------------------*/
string s, tmp, let = "01+-*()";
vi v;
int n, p, ans;

bool range(int t) { return t >= 0 && t < (1 << 10); }

int num() {
  int res = 0;
  while (p < n && isdigit(tmp[p])) {
    res *= 2;
    res += tmp[p] - '0';
    p++;
  }
  if (!range(res))
    return -1;
  return res;
}

pair<int, bool> plu();

int unit() {
  int res;
  if (tmp[p] == '(') {
    p++;
    auto a = plu();
    if (a.first == -1 || a.second == false || tmp[p] != ')')
      return -1;
    res = a.first;
    p++;
  } else {
    if (!isdigit(tmp[p]))
      return -1;
    res = num();
  }
  if (!range(res))
    return -1;
  else
    return res;
}

pair<int, bool> mul() {
  bool f = false;
  int res = unit();
  if (res == -1)
    return make_pair(-1, f);
  while (tmp[p] == '*') {
    if (!range(res))
      return make_pair(-1, f);
    f = true;
    p++;
    int rhs = unit();
    if (rhs == -1)
      return make_pair(-1, f);
    res *= rhs;
  }
  if (!range(res))
    return make_pair(-1, f);
  else
    return make_pair(res, f);
}

pair<int, bool> plu() {
  auto a = mul();
  int res = a.first;
  bool f = a.second;
  if (res == -1)
    return make_pair(-1, f);
  while (tmp[p] == '+' || tmp[p] == '-') {
    if (!range(res))
      return make_pair(-1, f);
    f = true;
    if (tmp[p] == '+') {
      p++;
      int rhs = mul().first;
      if (rhs == -1)
        return make_pair(-1, f);
      res += rhs;
    } else if (tmp[p] == '-') {
      p++;
      int rhs = mul().first;
      if (rhs == -1)
        return make_pair(-1, f);
      res -= rhs;
    }
  }
  if (!range(res))
    return make_pair(-1, f);
  else
    return make_pair(res, f);
}

int parse() {
  p = 0;
  int res = plu().first;
  if (p != tmp.size())
    return -1;
  else
    return res;
}

bool check1() {
  bool res = true;
  REP(i, tmp.size()) if (!isdigit(tmp[i])) res = false;
  return res;
}

bool check2() {
  bool res;
  string elem; // 0 = number, 1 = operator, 2 = '('
  REP(i, tmp.size()) {
    if (isdigit(tmp[i])) {
      while (isdigit(tmp[i]))
        i++;
      i--;
      elem.push_back('0');
    } else if (tmp[i] == '+' || tmp[i] == '-' || tmp[i] == '*') {
      elem.push_back('1');
    } else if (tmp[i] == '(')
      elem.push_back('(');
    else if (tmp[i] == ')')
      elem.push_back(')');
    else
      assert(false);
  }
  if (elem.size() > 2) {
    REP(i, elem.size() - 2) {
      if (elem[i] == '(' && elem[i + 1] == '0' && elem[i + 2] == ')')
        return false;
    }
  }
  if (elem.size() > 1) {
    REP(i, elem.size() - 1) {
      if (elem[i] == '(' && elem[i + 1] == ')')
        return false;
    }
  }
  return true;
}

void solve(int i, vi w) {
  if (i == v.size()) {
    tmp = s;
    REP(i, v.size()) { tmp[v[i]] = let[w[i]]; }
    p = 0;
    if (check1()) {
      int res = num();
      // if (res >= 0) cout << tmp << endl;
      chmax(ans, res);
    } else if (check2()) {
      int res = parse();
      // if (res >= 0) cout << tmp << endl;
      chmax(ans, res);
    }
  } else {
    REP(j, 7) {
      vi tmp = w;
      tmp.push_back(j);
      solve(i + 1, tmp);
    }
  }
}

int main() {
  ans = -1;
  cin >> s;
  n = s.size();
  REP(i, n) {
    if (s[i] == '.')
      v.push_back(i);
  }
  vi emp;
  solve(0, emp);
  cout << ans << endl;
  return 0;
}

Error: 0

Fixed submission:

#include <bits/stdc++.h>
using namespace std;
#define FOR(i, k, n) for (int i = (k); i < (n); i++)
#define REP(i, n) FOR(i, 0, n)
#define ALL(a) a.begin(), a.end()
#define MS(m, v) memset(m, v, sizeof(m))
#define D10 fixed << setprecision(10)
typedef long long ll;
typedef long double ld;
typedef vector<int> vi;
typedef vector<string> vs;
typedef pair<int, int> pii;
const int MOD = 1000000007;
const int INF = MOD + 1;
const ld EPS = 1e-12;
template <class T> T &chmin(T &a, const T &b) { return a = min(a, b); }
template <class T> T &chmax(T &a, const T &b) { return a = max(a, b); }

/*--------------------template--------------------*/
string s, tmp, let = "01+-*()";
vi v;
int n, p, ans;

bool range(int t) { return t >= 0 && t < (1 << 10); }

int num() {
  int res = 0;
  while (p < n && isdigit(tmp[p])) {
    res *= 2;
    res += tmp[p] - '0';
    p++;
  }
  if (!range(res))
    return -1;
  return res;
}

pair<int, bool> plu();

int unit() {
  int res;
  if (tmp[p] == '(') {
    p++;
    auto a = plu();
    if (a.second == false || tmp[p] != ')')
      return -1;
    res = a.first;
    p++;
  } else {
    if (!isdigit(tmp[p]))
      return -1;
    res = num();
  }
  if (!range(res))
    return -1;
  else
    return res;
}

pair<int, bool> mul() {
  bool f = false;
  int res = unit();
  while (tmp[p] == '*') {
    f = true;
    p++;
    int rhs = unit();
    if (rhs == -1)
      return make_pair(-1, f);
    res *= rhs;
  }
  if (!range(res))
    return make_pair(-1, f);
  else
    return make_pair(res, f);
}

pair<int, bool> plu() {
  auto a = mul();
  int res = a.first;
  bool f = a.second;
  if (res == -1)
    return make_pair(-1, f);
  while (tmp[p] == '+' || tmp[p] == '-') {
    f = true;
    if (tmp[p] == '+') {
      p++;
      int rhs = mul().first;
      if (rhs == -1)
        return make_pair(-1, f);
      res += rhs;
    } else if (tmp[p] == '-') {
      p++;
      int rhs = mul().first;
      if (rhs == -1)
        return make_pair(-1, f);
      res -= rhs;
    }
  }
  if (!range(res))
    return make_pair(-1, f);
  else
    return make_pair(res, f);
}

int parse() {
  p = 0;
  int res = plu().first;
  if (p != tmp.size())
    return -1;
  else
    return res;
}

bool check1() {
  bool res = true;
  REP(i, tmp.size()) if (!isdigit(tmp[i])) res = false;
  return res;
}

bool check2() {
  bool res;
  string elem; // 0 = number, 1 = operator, 2 = '('
  REP(i, tmp.size()) {
    if (isdigit(tmp[i])) {
      while (isdigit(tmp[i]))
        i++;
      i--;
      elem.push_back('0');
    } else if (tmp[i] == '+' || tmp[i] == '-' || tmp[i] == '*') {
      elem.push_back('1');
    } else if (tmp[i] == '(')
      elem.push_back('(');
    else if (tmp[i] == ')')
      elem.push_back(')');
    else
      assert(false);
  }
  REP(i, elem.size() - 2) {
    if (elem[i] == '(' && elem[i + 1] == '0' && elem[i + 2] == ')')
      return false;
  }
  REP(i, elem.size() - 1) {
    if (elem[i] == '(' && elem[i + 1] == ')')
      return false;
  }
  return true;
}

void solve(int i, vi w) {
  if (i == v.size()) {
    tmp = s;
    REP(i, v.size()) { tmp[v[i]] = let[w[i]]; }
    p = 0;
    if (check1()) {
      int res = num();
      chmax(ans, res);
    } else if (check2()) {
      int res = parse();
      chmax(ans, res);
    }
  } else {
    REP(j, 7) {
      vi tmp = w;
      tmp.push_back(j);
      solve(i + 1, tmp);
    }
  }
}

int main() {
  ans = -1;
  cin >> s;
  n = s.size();
  REP(i, n) {
    if (s[i] == '.')
      v.push_back(i);
  }
  vi emp;
  solve(0, emp);
  cout << ans << endl;
  return 0;
}