Problem p00736 (C++) — buggy submission, verdict: Time Limit Exceeded

#include <algorithm>
#include <bitset>
#include <cctype>
#include <cmath>
#include <complex>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <ctime>
#include <deque>
#include <fstream>
#include <functional>
#include <iomanip>
#include <iostream>
#include <list>
#include <map>
#include <numeric>
#include <queue>
#include <set>
#include <sstream>
#include <stack>
#include <string>
#include <utility>
#include <vector>

#define INF 100000000
#define EPS 1e-9

using namespace std;

typedef long long ll;

int P, Q, R;
string str, tmpStr;

int myNot[] = {2, 1, 0};
int myAnd[3][3] = {{0, 0, 0}, {0, 1, 1}, {0, 1, 2}};
int myOr[3][3] = {{0, 1, 2}, {1, 1, 2}, {2, 2, 2}};

vector<int> ans_list;

// 左から何番目を基準にしているか
bool solve(int num) {

  int tmai = 0;
  int s = -1;
  if (tmpStr[num] == '-')
    tmai++;

  for (int i = num + 1; i < tmpStr.length(); i++) {
    if (tmpStr[i] == '(') {
      solve(i);
      break;
    } else if (tmpStr[i] == ')') {
      int mai = 0; // マイナスが何回現れたか
      int left = -1;
      int right = -1; // 左と右の数字
      int ope = -1;   // 1:ans 2:or
      for (int k = num + 1; k < i; k++) {
        if (tmpStr[k] == '-')
          mai++;
        else if (tmpStr[k] == '*')
          ope = 1;
        else if (tmpStr[k] == '+')
          ope = 2;
        else {
          mai %= 2;
          int tmp = tmpStr[k] - '0';
          if (left == -1)
            left = tmp;
          else
            right = tmp;
          mai = 0;
        }
      }
      int tmp = -1;
      if (ope == 1)
        tmp = myAnd[left][right];
      else
        tmp = myOr[left][right];
      tmpStr.erase(num, i - num + 1);
      tmpStr.insert(tmpStr.begin() + num, tmp + '0');
      break;
    }

    else if (tmpStr[i] == '-') {
      tmai++;
      if (s == -1)
        s = i;
    }
    if (tmai > 0 && '0' <= tmpStr[i] && tmpStr[i] <= '2') {
      int t = tmpStr[i] - '0';
      if (tmai % 2 == 1)
        t = myNot[t];
      if (tmpStr[num] == '-') {
        tmpStr.erase(num, i - num + 1);
        tmpStr.insert(tmpStr.begin() + num, t + '0');
      } else {
        tmpStr.erase(s, i - s + 1);
        tmpStr.insert(tmpStr.begin() + s, t + '0');
      }
      break;
    }
  }

  // 文字の長さが1なら、それが2になっているかの判定
  if (tmpStr.length() == 1) {
    if (tmpStr == "2")
      return true;
    else
      return false;
  }

  return false;
}

int main() {

  while (true) {

    cin >> str;
    if (str == ".")
      break;

    int ans = 0;
    for (int i = 0; i < 27; i++) {
      P = i % 3;
      Q = (i / 3) % 3;
      R = (i / 9) % 3;
      tmpStr.clear();
      tmpStr = str;

      for (int i = 0; i < tmpStr.length(); i++) {
        if (tmpStr[i] == 'P')
          tmpStr[i] = P + '0';
        else if (tmpStr[i] == 'Q')
          tmpStr[i] = Q + '0';
        else if (tmpStr[i] == 'R')
          tmpStr[i] = R + '0';
      }

      while (true) {
        if (tmpStr.length() != 1)
          solve(0);
        else
          break;
      }

      if (solve(0))
        ans++;
    }

    ans_list.push_back(ans);
  }

  for (int i = 0; i < ans_list.size(); i++) {
    cout << ans_list[i] << endl;
  }

  return 0;
}

Error: TLE

Fixed submission:

#include <algorithm>
#include <bitset>
#include <cctype>
#include <cmath>
#include <complex>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <ctime>
#include <deque>
#include <fstream>
#include <functional>
#include <iomanip>
#include <iostream>
#include <list>
#include <map>
#include <numeric>
#include <queue>
#include <set>
#include <sstream>
#include <stack>
#include <string>
#include <utility>
#include <vector>

#define INF 100000000
#define EPS 1e-9

using namespace std;

typedef long long ll;

int P, Q, R;
string str, tmpStr;

int myNot[] = {2, 1, 0};
int myAnd[3][3] = {{0, 0, 0}, {0, 1, 1}, {0, 1, 2}};
int myOr[3][3] = {{0, 1, 2}, {1, 1, 2}, {2, 2, 2}};

vector<int> ans_list;

// 左から何番目を基準にしているか
bool solve(int num) {

  for (int i = num + 1; i < tmpStr.length(); i++) {
    if (tmpStr[i] == '(') {
      solve(i);
      break;
    } else if (tmpStr[i] == ')') {
      int mai = 0; // マイナスが何回現れたか
      int left = -1;
      int right = -1; // 左と右の数字
      int ope = -1;   // 1:ans 2:or
      for (int k = num + 1; k < i; k++) {
        if (tmpStr[k] == '-')
          mai++;
        else if (tmpStr[k] == '*')
          ope = 1;
        else if (tmpStr[k] == '+')
          ope = 2;
        else {
          mai %= 2;
          int tmp = tmpStr[k] - '0';
          if (mai == 1)
            tmp = myNot[tmp];
          if (left == -1)
            left = tmp;
          else
            right = tmp;
          mai = 0;
        }
      }
      int tmp = -1;
      if (ope == 1)
        tmp = myAnd[left][right];
      else
        tmp = myOr[left][right];
      tmpStr.erase(num, i - num + 1);
      tmpStr.insert(tmpStr.begin() + num, tmp + '0');
      break;
    }
  }

  // 文字の長さが1なら、それが2になっているかの判定
  if (tmpStr.length() == 1) {
    if (tmpStr == "2")
      return true;
    else
      return false;
  }

  return false;
}

int main() {

  while (true) {

    cin >> str;
    if (str == ".")
      break;

    int ans = 0;
    for (int i = 0; i < 27; i++) {
      P = i % 3;
      Q = (i / 3) % 3;
      R = (i / 9) % 3;
      tmpStr.clear();
      tmpStr = str;

      for (int i = 0; i < tmpStr.length(); i++) {
        if (tmpStr[i] == 'P')
          tmpStr[i] = P + '0';
        else if (tmpStr[i] == 'Q')
          tmpStr[i] = Q + '0';
        else if (tmpStr[i] == 'R')
          tmpStr[i] = R + '0';
      }

      while (true) {
        if (tmpStr.length() != 1)
          solve(0);
        else
          break;
      }

      if (solve(0))
        ans++;
    }

    ans_list.push_back(ans);
  }

  for (int i = 0; i < ans_list.size(); i++) {
    cout << ans_list[i] << endl;
  }

  return 0;
}