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

#include <bits/stdc++.h>
#define r(i, n) for (int i = 0; i < n; i++)
using namespace std;

std::chrono::system_clock::time_point start;
std::chrono::system_clock::time_point owari;

string A[51], s;
int h, w, p, d, y, x, cnt;
int dy[] = {-1, 0, 1, 0};
int dx[] = {0, 1, 0, -1};

void IF();

void END() {
  cout << cnt << endl;
  exit(0);
}

void BAD_END() {
  cout << -1 << endl;
  exit(0);
}

bool OK() {
  owari = std::chrono::system_clock::now();
  double elapsed =
      std::chrono::duration_cast<std::chrono::milliseconds>(owari - start)
          .count();
  return elapsed <= 1999.999;
}

bool BOOL() {
  if (!OK())
    BAD_END();
  bool res = 0;
  if (s[p] == '~')
    res ^= 1, p++;
  if (s[p] == 'N' && d == 0)
    res ^= 1;
  if (s[p] == 'E' && d == 1)
    res ^= 1;
  if (s[p] == 'S' && d == 2)
    res ^= 1;
  if (s[p] == 'W' && d == 3)
    res ^= 1;
  if (s[p] == 'C' && A[y + dy[d]][x + dx[d]] == '#')
    res ^= 1;
  if (s[p] == 'T')
    res ^= 1;
  p++;
  return res;
}
void MOVE() {
  if (!OK())
    BAD_END();
  cnt++;
  if (s[p] == '^') {
    int ny = y + dy[d];
    int nx = x + dx[d];
    if (A[ny][nx] != '#')
      y = ny, x = nx;
  }
  if (s[p] == 'v') {
    int ny = y - dy[d];
    int nx = x - dx[d];
    if (A[ny][nx] != '#')
      y = ny, x = nx;
  }
  if (s[p] == '<')
    d = (d + 3) % 4;
  if (s[p] == '>')
    d = (d + 1) % 4;
  p++;

  if (A[y][x] == 'g')
    END();
}
void WHILE() {
  if (!OK())
    BAD_END();
  int idx = ++p;
  while (1) {
    bool res = BOOL();
    if (!res) {
      stack<int> st;
      st.push(1);
      while (st.size()) {
        if (s[p] == '{')
          st.push(1);
        if (s[p] == '}')
          st.pop();
        p++;
      }
      return;
    }
    while (s[p] != '}') {
      if (s[p] == '{')
        WHILE();
      else if (s[p] == '[')
        IF();
      else
        MOVE();
    }
    p = idx;
  }
  p++;
}
void IF() {
  if (!OK())
    BAD_END();
  p++;
  bool res = BOOL();
  if (!res) {
    stack<int> st;
    st.push(1);
    while (st.size()) {
      if (s[p] == '[')
        st.push(1);
      if (s[p] == ']')
        st.pop();
      p++;
    }
    return;
  }
  while (s[p] != ']') {
    if (s[p] == '{')
      WHILE();
    else if (s[p] == '[')
      IF();
    else
      MOVE();
  }
  p++;
}

void bnf() {
  while (s[p] != '@') {
    if (s[p] == '{')
      WHILE();
    else if (s[p] == '[')
      IF();
    else
      MOVE();
  }
}

int main() {
  start = std::chrono::system_clock::now();
  cin >> h >> w;
  r(i, h) cin >> A[i];
  r(i, h) r(j, w) if (A[i][j] == 's') y = i, x = j;
  cin >> s;
  s += '@';
  bnf();
  BAD_END();
}


Error: TLE

Fixed submission:

#include <bits/stdc++.h>
#define r(i, n) for (int i = 0; i < n; i++)
using namespace std;

std::chrono::system_clock::time_point start;
std::chrono::system_clock::time_point owari;

string A[51], s;
int h, w, p, d, y, x, cnt;
int dy[] = {-1, 0, 1, 0};
int dx[] = {0, 1, 0, -1};

void IF();

void END() {
  cout << cnt << endl;
  exit(0);
}

void BAD_END() {
  cout << -1 << endl;
  exit(0);
}

bool OK() {
  owari = std::chrono::system_clock::now();
  double elapsed =
      std::chrono::duration_cast<std::chrono::milliseconds>(owari - start)
          .count();
  return 1;
}

bool BOOL() {
  if (!OK())
    BAD_END();
  bool res = 0;
  if (s[p] == '~')
    res ^= 1, p++;
  if (s[p] == 'N' && d == 0)
    res ^= 1;
  if (s[p] == 'E' && d == 1)
    res ^= 1;
  if (s[p] == 'S' && d == 2)
    res ^= 1;
  if (s[p] == 'W' && d == 3)
    res ^= 1;
  if (s[p] == 'C' && A[y + dy[d]][x + dx[d]] == '#')
    res ^= 1;
  if (s[p] == 'T')
    res ^= 1;
  p++;
  return res;
}
void MOVE() {
  if (!OK())
    BAD_END();
  cnt++;
  if (s[p] == '^') {
    int ny = y + dy[d];
    int nx = x + dx[d];
    if (A[ny][nx] != '#')
      y = ny, x = nx;
  }
  if (s[p] == 'v') {
    int ny = y - dy[d];
    int nx = x - dx[d];
    if (A[ny][nx] != '#')
      y = ny, x = nx;
  }
  if (s[p] == '<')
    d = (d + 3) % 4;
  if (s[p] == '>')
    d = (d + 1) % 4;
  p++;

  if (A[y][x] == 'g')
    END();
}
void WHILE() {
  if (!OK())
    BAD_END();
  int idx = ++p;
  while (1) {
    bool res = BOOL();
    if (!res) {
      stack<int> st;
      st.push(1);
      while (st.size()) {
        if (s[p] == '{')
          st.push(1);
        if (s[p] == '}')
          st.pop();
        p++;
      }
      return;
    }
    while (s[p] != '}') {
      if (s[p] == '{')
        WHILE();
      else if (s[p] == '[')
        IF();
      else
        MOVE();
    }
    p = idx;
  }
  p++;
}
void IF() {
  if (!OK())
    BAD_END();
  p++;
  bool res = BOOL();
  if (!res) {
    stack<int> st;
    st.push(1);
    p++;
    while (st.size()) {
      if (s[p] == '[')
        st.push(1);
      if (s[p] == ']')
        st.pop();
      p++;
    }
    return;
  }
  while (s[p] != ']') {
    if (s[p] == '{')
      WHILE();
    else if (s[p] == '[')
      IF();
    else
      MOVE();
  }
  p++;
}

void bnf() {
  while (s[p] != '@') {
    if (s[p] == '{')
      WHILE();
    else if (s[p] == '[')
      IF();
    else
      MOVE();
  }
}

int main() {
  start = std::chrono::system_clock::now();
  cin >> h >> w;
  r(i, h) cin >> A[i];
  r(i, h) r(j, w) if (A[i][j] == 's') y = i, x = j;
  cin >> s;
  s += '@';
  bnf();
  BAD_END();
}