Problem p00736 (C++)

Buggy submission (status: Runtime Error):
#include <algorithm>
#include <fstream>
#include <functional>
#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);

// p,q,rに代入(これで、P,Q,Rが消滅)
string substitute(string s, int p, int q, int r) {
  REP(i, s.size()) {
    switch (s[i]) {
    case 'P':
      s[i] = '0' + p;
      break;
    case 'Q':
      s[i] = '0' + q;
      break;
    case 'R':
      s[i] = '0' + r;
      break;
    }
  }
  return s;
}

// 末尾にある数値に対して、インバースを適用(これで、-が消滅)
void apply_inverse(stack<char> &info) {
  char t = info.top();
  if (t < '0' || '2' < t)
    return;
  info.pop();

  while (!info.empty() && info.top() == '-') {
    info.pop();
    if (t == '2')
      t = '0';
    else if (t == '0')
      t = '2';
  }
  info.push(t);
}

// 演算子を実際に適用(これで、(,+,*,)が消滅 )
void apply_operator(stack<char> &info) {
  char r = info.top();
  info.pop();
  char ope = info.top();
  info.pop();
  char l = info.top();
  info.pop();

  char err = info.top();
  info.pop();
  if (err != '(') {
    exit(1);
  }
  l -= '0';
  r -= '0';
  char res;
  switch (ope) {
  case '+':
    if (max(l, r) == 2)
      res = '2';
    else if (l + r == 0)
      res = '0';
    else
      res = '1';
    break;
  case '*':
    if (min(l, r) == 0)
      res = '0';
    else if (l + r == 4)
      res = '2';
    else
      res = '1';
    break;
  default:
    exit(1);
  }
  info.push(res);
}

// 構文を実際に計算する
bool play(const string &s) {
  stack<char> info;
  for (const char &c : s) {
    switch (c) {
    case '0':
    case '1':
    case '2':
      info.push(c);
      apply_inverse(info);
      break;
    case ')':
      apply_operator(info);
      apply_inverse(info);
      break;
    default:
      info.push(c);
      break;
    }
  }

  if (info.size() != 1) {
    exit(1);
  } else {
    return info.top() == '2';
  }
}

// 全探索を行う
void calc(const string &formula) {
  int res = 0;
  REP(p, 3) REP(q, 3) REP(r, 3) {
    string target = substitute(formula, p, q, r);
    if (play(target)) {
      res++;
    }
  }

  cout << res << endl;
}

// メイン関数
int main() {
  while (true) {
    string formula;
    cin >> formula;

    if (formula == ".")
      break;
    calc(formula);
  }

  return 0;
}


Fixed submission:
#include <algorithm>
#include <fstream>
#include <functional>
#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);

// p,q,rに代入(これで、P,Q,Rが消滅)
string substitute(string s, int p, int q, int r) {
  REP(i, s.size()) {
    switch (s[i]) {
    case 'P':
      s[i] = '0' + p;
      break;
    case 'Q':
      s[i] = '0' + q;
      break;
    case 'R':
      s[i] = '0' + r;
      break;
    }
  }
  return s;
}

// 末尾にある数値に対して、インバースを適用(これで、-が消滅)
void apply_inverse(stack<char> &info) {
  char t = info.top();
  if (t < '0' || '2' < t)
    return;
  info.pop();

  while (!info.empty() && info.top() == '-') {
    info.pop();
    if (t == '2')
      t = '0';
    else if (t == '0')
      t = '2';
  }
  info.push(t);
}

// 演算子を実際に適用(これで、(,+,*,)が消滅 )
void apply_operator(stack<char> &info) {
  char r = info.top();
  info.pop();
  char ope = info.top();
  info.pop();
  char l = info.top();
  info.pop();

  char err = info.top();
  info.pop();
  if (err != '(') {
    exit(1);
  }
  l -= '0';
  r -= '0';
  char res;
  switch (ope) {
  case '+':
    if (max(l, r) == 2)
      res = '2';
    else if (l + r == 0)
      res = '0';
    else
      res = '1';
    break;
  case '*':
    if (min(l, r) == 0)
      res = '0';
    else if (l + r == 4)
      res = '2';
    else
      res = '1';
    break;
  default:
    exit(1);
  }
  info.push(res);
}

// 構文を実際に計算する
bool play(string s) {
  stack<char> info;
  for (const char &c : s) {
    switch (c) {
    case '0':
    case '1':
    case '2':
      info.push(c);
      apply_inverse(info);
      break;
    case ')':
      apply_operator(info);
      apply_inverse(info);
      break;
    default:
      info.push(c);
      break;
    }
  }

  if (info.size() != 1) {
    exit(1);
  } else {
    return info.top() == '2';
  }
}

// 全探索を行う
void calc(const string &formula) {
  int res = 0;
  REP(p, 3) REP(q, 3) REP(r, 3) {
    string target = substitute(formula, p, q, r);
    if (play(target)) {
      res++;
    }
  }

  cout << res << endl;
}

// メイン関数
int main() {
  while (true) {
    string formula;
    cin >> formula;

    if (formula == ".")
      break;
    calc(formula);
  }

  return 0;
}