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

#include <algorithm>
#include <fstream>
#include <functional>
#include <iomanip>
#include <iostream>
#include <list>
#include <math.h>
#include <queue>
#include <set>
#include <stack>
#include <stdlib.h>
#include <string>
#include <vector>

#define FOR(k, m, n) for (int(k) = (m); (k) < (n); (k)++)
#define REP(i, n) FOR((i), 0, (n))
#define LL long long
#define CLR(a) memset((a), 0, sizeof(a))
#define SZ(x) (int((x).size()))
#define WAITING(str)                                                           \\
  int str;                                                                     \\
  std::cin >> str;
#define DEBUGING(str) cout << str << endl
using namespace std;

const LL MOD = 1000000007; // 10^9+7
const int INF = (1 << 30);

struct Stage {
  const int kind = 7;
  Stage() {}

  void action() {
    string text;
    cin >> text;

    int res = -1;
    REP(transWay, pow(kind, count_dot(text))) {
      string transedText = trans(transWay, text);
      list<char> ls;
      for (char c : transedText)
        ls.push_back(c);
      auto grams = trans_gram(ls);
      if (grams.empty())
        continue;
      int score = read(grams);

      res = max(res, score);
    }
    cout << res << endl;
  }

private:
  struct Gram {
    char kind;
    char data;
    int num;
  };

  int count_dot(const string &text) {
    int res = 0;
    for (char c : text)
      if (c == '.')
        res++;
    return res;
  }
  string trans(int n, string text) {
    for (char &c : text)
      if (c == '.') {
        switch (n % kind) {
        case 0:
          c = '0';
          break;
        case 1:
          c = '1';
          break;
        case 2:
          c = '+';
          break;
        case 3:
          c = '-';
          break;
        case 4:
          c = '*';
          break;
        case 5:
          c = '(';
          break;
        case 6:
          c = ')';
          break;
        }
        n /= kind;
      }
    return text;
  }

  list<Gram> trans_gram(const list<char> &ls) {
    list<Gram> grams;
    for (auto itr = ls.begin(); itr != ls.end(); ++itr) {
      Gram gram;
      switch (*itr) {
      case '+':
        gram.kind = 'o';
        gram.data = '+';
        // gram.num = 0;
        break;
      case '-':
        gram.kind = 'o';
        gram.data = '-';
        // gram.num = 0;
        break;
      case '*':
        gram.kind = 'o';
        gram.data = '*';
        // gram.num = 0;
        break;
      case '(':
        gram.kind = 'p';
        gram.data = '(';
        // gram.num = 0;
        break;
      case ')':
        gram.kind = 'p';
        gram.data = ')';
        // gram.num = 0;
        break;
      default:
        gram.kind = 'n';
        gram.data = 't';
        gram.num = 0;
        do {
          gram.num *= 2;
          gram.num += *itr - '0';
          ++itr;
        } while (itr != ls.end() && isDigit(*itr));
        if (!isvalid(gram.num))
          return list<Gram>();
        --itr;
        break;
      }
      grams.push_back(gram);
    }
    return grams;
  }

  int read(list<Gram> grams) {
    try {
      // ( , ) delete
      for (auto right = grams.begin(); right != grams.end(); ++right) {
        if (right->data == ')') {
          list<Gram> subset;
          auto left = right;

          // move: (expression)
          while (left != grams.begin() && left->data != '(')
            --left;
          if (left->data != '(')
            throw -1;
          ++right;
          subset.splice(subset.begin(), move(grams), left, right);

          // delete: ( , )
          subset.pop_front();
          subset.pop_back();

          if (subset.size() == 1)
            throw -1;

          int res = read(subset);
          if (res < 0)
            throw -1;
          if (1024 <= res)
            throw -1;

          Gram gram;
          gram.kind = 'n';
          gram.num = res;
          grams.insert(right, gram);
          right = grams.begin();
        }
      }

      operator_erase(grams, '*', '*');
      operator_erase(grams, '+', '-');
      if (grams.size() != 1) {
        // cerr << "size is too much" << endl;
        throw -1;
      } else {
        if (grams.front().kind != 'n')
          throw -1;

        int res = grams.front().num;
        if (!isvalid(res))
          throw -1;
        else
          return res;
      }
    } catch (...) {
      return -1;
    }
  }

  bool isvalid(int num) { return 0 <= num && num < 1024; }

  bool isDigit(char c) { return '0' <= c && c <= '9'; }

  bool isnumber(const list<char> &ls) {
    for (char c : ls) {
      if (!isDigit(c)) {
        return false;
      }
    }
    return true;
  }

  bool isoperator(const char &c) {
    switch (c) {
    case '+':
    case '-':
    case '*':
      return true;
    default:
      return false;
    }
  }

  void operator_erase(list<Gram> &grams, char ope1, char ope2) {
    for (auto center = grams.begin(); center != grams.end(); ++center) {
      if (center->data == ope1 || center->data == ope2) {
        auto left = center;
        if (distance(grams.begin(), left) == 0)
          break;
        left--;
        auto right = center;
        if (distance(right, grams.end()) == 1)
          break;
        right++;
        if (left->kind != 'n' || right->kind != 'n')
          continue;

        switch (center->data) {
        case '+':
          left->num += right->num;
          break;
        case '-':
          left->num -= right->num;
          break;
        case '*':
          left->num *= right->num;
          break;
        }

        if (!isvalid(left->num))
          throw -1;
        grams.erase(center);
        grams.erase(right);
        center = left;
      }
    }
  }
};

// デバッグ
void debug() {
  int N;
  cin >> N;
}

// メイン関数
int main() {
  Stage stage;
  stage.action();
  debug();

  return 0;
}


Error: 0

Fixed submission:

#include <algorithm>
#include <fstream>
#include <functional>
#include <iomanip>
#include <iostream>
#include <list>
#include <math.h>
#include <queue>
#include <set>
#include <stack>
#include <stdlib.h>
#include <string>
#include <vector>

#define FOR(k, m, n) for (int(k) = (m); (k) < (n); (k)++)
#define REP(i, n) FOR((i), 0, (n))
#define LL long long
#define CLR(a) memset((a), 0, sizeof(a))
#define SZ(x) (int((x).size()))
#define WAITING(str)                                                           \\
  int str;                                                                     \\
  std::cin >> str;
#define DEBUGING(str) cout << str << endl
using namespace std;

const LL MOD = 1000000007; // 10^9+7
const int INF = (1 << 30);

struct Stage {
  const int kind = 7;
  Stage() {}

  void action() {
    string text;
    cin >> text;

    int res = -1;
    REP(transWay, pow(kind, count_dot(text))) {
      string transedText = trans(transWay, text);
      list<char> ls;
      for (char c : transedText)
        ls.push_back(c);
      int score = read(ls);
      res = max(res, score);
    }
    cout << res << endl;
  }

private:
  struct Gram {
    char kind;
    char data;
    int num;
  };

  int count_dot(const string &text) {
    int res = 0;
    for (char c : text)
      if (c == '.')
        res++;
    return res;
  }
  string trans(int n, string text) {
    for (char &c : text)
      if (c == '.') {
        switch (n % kind) {
        case 0:
          c = '0';
          break;
        case 1:
          c = '1';
          break;
        case 2:
          c = '+';
          break;
        case 3:
          c = '-';
          break;
        case 4:
          c = '*';
          break;
        case 5:
          c = '(';
          break;
        case 6:
          c = ')';
          break;
        }
        n /= kind;
      }
    return text;
  }

  list<Gram> trans_gram(const list<char> &ls) {
    list<Gram> grams;
    for (auto itr = ls.begin(); itr != ls.end(); ++itr) {
      Gram gram;
      switch (*itr) {
      case '+':
        gram.kind = 'o';
        gram.data = '+';
        break;
      case '-':
        gram.kind = 'o';
        gram.data = '-';
        break;
      case '*':
        gram.kind = 'o';
        gram.data = '*';
        break;
      default:
        gram.kind = 'n';
        gram.num = 0;
        do {
          gram.num *= 2;
          gram.num += *itr - '0';
          ++itr;
        } while (itr != ls.end() && isdigit(*itr));
        --itr;
        break;
      }
      grams.push_back(gram);
    }
    return grams;
  }

  int read(list<char> ls) {
    try {
      // ( , ) delete
      for (auto right = ls.begin(); right != ls.end(); ++right) {
        if (*right == ')') {
          list<char> subset;
          auto left = right;

          // move: (expression)
          while (left != ls.begin() && *left != '(')
            --left;
          if (*left != '(')
            throw -1;
          ++right;
          subset.splice(subset.begin(), move(ls), left, right);

          // delete: ( , )
          subset.pop_front();
          subset.pop_back();
          if (isnumber(subset))
            throw -1;

          int res = read(subset);
          if (res < 0)
            throw -1;
          subset = n2b(res);
          if (ls.empty()) {
            for (auto num : subset)
              ls.push_back(num);
          } else {
            ls.splice(left, move(subset));
          }
          right = ls.begin();
        }
      }

      auto grams = trans_gram(ls);
      operator_erase(grams, '*');
      operator_erase(grams, '+', '-');
      if (grams.size() != 1) {
        // cerr << "size is too much" << endl;
        throw -1;
      } else {
        return grams.front().num;
      }
    } catch (...) {
      return -1;
    }
  }

  bool isnumber(const list<char> &ls) {
    for (char c : ls) {
      if (c < '0' || '9' < c) {
        return false;
      }
    }
    return true;
  }

  bool isoperator(const char &c) {
    switch (c) {
    case '+':
    case '-':
    case '*':
      return true;
    default:
      return false;
    }
  }

  list<char> n2b(int num) {
    list<char> b;
    while (num > 0) {
      int tmp = num % 2;
      num /= 2;
      b.push_front(tmp + '0');
    }
    return b;
  }

  int b2n(const list<char> &ls) {
    int res = 0;
    for (char c : ls) {
      res *= 2;
      res += c - '0';
    }
    return res;
  }

  void operator_erase(list<Gram> &grams, const char &ope1,
                      const char &ope2 = '.') {
    for (auto center = grams.begin(); center != grams.end(); ++center) {
      if (center->data == ope1 || center->data == ope2) {
        auto left = center;
        if (distance(grams.begin(), left) == 0)
          break;
        left--;
        auto right = center;
        if (distance(right, grams.end()) == 1)
          break;
        right++;

        switch (center->data) {
        case '+':
          left->num += right->num;
          break;
        case '-':
          left->num -= right->num;
          break;
        case '*':
          left->num *= right->num;
          break;
        }

        if (left->num < 0 || 1024 <= left->num)
          throw -1;
        grams.erase(center);
        grams.erase(right);
        center = left;
      }
    }
  }
};

// デバッグ
void debug() {
  int N;
  cin >> N;
}

// メイン関数
int main() {
  Stage stage;
  stage.action();
  debug();

  return 0;
}