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

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;

map<char, int> dm;
int H, W;
string s;
string b[50];
int dp[50][50][4][1010];
int gx, gy;
int nx, ny;
int dir = 3;
int ans;
int c;

// E, S, W, N
int dx[4] = {1, 0, -1, 0}, dy[4] = {0, 1, 0, -1};

void GO() {
  // cerr << "GO" << endl;
  int x = nx + dx[dir], y = ny + dy[dir];
  if (b[y][x] == '#')
    return;
  nx = x, ny = y;
}
void BACK() {
  // cerr << "BACK" << endl;
  int x = nx - dx[dir], y = ny - dy[dir];
  if (b[y][x] == '#')
    return;
  nx = x, ny = y;
}

void TURN_L() {
  // cerr << "TURN_L" << endl;
  dir = (dir + 3) % 4;
}

void TURN_R() {
  // cerr << "TURN_R" << endl;
  dir = (dir + 1) % 4;
}

void P();
void IF();
void WHILE();
bool COND(string s);

void IF() {
  c++; // [
  string cond;
  if (s[c] == '~')
    cond += s[c++];
  cond += s[c++];
  if (COND(cond)) {
    P();
    assert(s[c] == ']');
    c++;
  } else {
    int t = 1;
    while (t > 0) {
      if (s[c] == ']')
        t--;
      if (s[c] == '[')
        t++;
      c++;
    }
  }
}

void WHILE() {
  c++; // {
  int tc = c;
  while (c < s.size() && !(nx == gx && ny == gy)) {
    string cond;
    if (s[c] == '~')
      cond += s[c++];
    cond += s[c++];
    if (COND(cond)) {
      do {
        P();
      } while (s[c] != '}');
      c = tc;
      continue;
    } else {
      int t = 1;
      while (t > 0) {
        if (s[c] == '}')
          t--;
        if (s[c] == '{')
          t++;
        c++;
      }
      break;
    }
  }
}

void P() {
  if (c < s.size() && !(nx == gx && ny == gy)) {
    // cerr << s[c] << endl;
    if (dp[ny][nx][dir][c])
      throw -1;
    dp[ny][nx][dir][c] = 1;

    if (s[c] == '^') {
      GO();
      c++;
      ans++;
      if (nx == gx && ny == gy)
        throw ans;
      if (ans == 1000000)
        throw -1;
      P();
    }
    if (s[c] == 'v') {
      BACK();
      c++;
      ans++;
      if (nx == gx && ny == gy)
        throw ans;
      if (ans == 10000000)
        throw -1;
      P();
    }
    if (s[c] == '<') {
      TURN_L();
      c++;
      ans++;
      if (ans == 10000000)
        throw -1;
      P();
    }
    if (s[c] == '>') {
      TURN_R();
      c++;
      ans++;
      if (ans == 10000000)
        throw -1;
      P();
    }
    if (s[c] == '{') {
      WHILE();
      P();
    }
    if (s[c] == '[') {
      IF();
      P();
    }
  }
}

bool COND(string s) {
  bool NOT = false;
  if (s.size() == 2) {
    NOT = true;
    s = s.substr(1, 1);
  }

  if (s == "T")
    return true ^ NOT;
  if (s == "C") {
    int x = nx + dx[dir], y = ny + dy[dir];
    return (b[y][x] == '#') ^ NOT;
  }
  return (dm[s[0]] == dir) ^ NOT;
}

int main() {
  cin.tie(0);
  ios::sync_with_stdio(false);

  dm['E'] = 0;
  dm['S'] = 1;
  dm['W'] = 2;
  dm['N'] = 3;

  cin >> H >> W;
  for (int i = 0; i < H; i++) {
    cin >> b[i];
    for (int j = 0; j < W; j++) {
      if (b[i][j] == 'g') {
        gx = j, gy = i;
        b[i][j] = '.';
      }
      if (b[i][j] == 's') {
        nx = j, ny = i;
        b[i][j] = '.';
      }
    }
  }
  cin >> s;

  dir = dm['N'];
  try {
    P();
  } catch (int x) {
    cout << x << endl;
    return 0;
  };
  cout << -1 << endl;
}

Error: TLE

Fixed submission:

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;

map<char, int> dm;
int H, W;
string s;
string b[50];
int dp[50][50][4][1010];
int gx, gy;
int nx, ny;
int dir = 3;
int ans;
int c;

// E, S, W, N
int dx[4] = {1, 0, -1, 0}, dy[4] = {0, 1, 0, -1};

void GO() {
  // cerr << "GO" << endl;
  int x = nx + dx[dir], y = ny + dy[dir];
  if (b[y][x] == '#')
    return;
  nx = x, ny = y;
}
void BACK() {
  // cerr << "BACK" << endl;
  int x = nx - dx[dir], y = ny - dy[dir];
  if (b[y][x] == '#')
    return;
  nx = x, ny = y;
}

void TURN_L() {
  // cerr << "TURN_L" << endl;
  dir = (dir + 3) % 4;
}

void TURN_R() {
  // cerr << "TURN_R" << endl;
  dir = (dir + 1) % 4;
}

void P();
void IF();
void WHILE();
bool COND(string s);

void IF() {
  c++; // [
  string cond;
  if (s[c] == '~')
    cond += s[c++];
  cond += s[c++];
  if (COND(cond)) {
    P();
  } else {
    int t = 1;
    while (t > 0) {
      if (s[c] == ']')
        t--;
      if (s[c] == '[')
        t++;
      c++;
    }
  }
}

void WHILE() {
  c++; // {
  int tc = c;
  while (c < s.size() && !(nx == gx && ny == gy)) {
    string cond;
    if (s[c] == '~')
      cond += s[c++];
    cond += s[c++];
    if (COND(cond)) {
      while (s[c] != '}')
        P();
      c = tc;
      continue;
    } else {
      int t = 1;
      while (t > 0) {
        if (s[c] == '}')
          t--;
        if (s[c] == '{')
          t++;
        c++;
      }
      break;
    }
  }
}

void P() {
  if (c < s.size() && !(nx == gx && ny == gy)) {
    // cerr << s[c] << endl;
    if (dp[ny][nx][dir][c])
      throw -1;
    dp[ny][nx][dir][c] = 1;

    if (s[c] == '^') {
      GO();
      c++;
      ans++;
      if (nx == gx && ny == gy)
        throw ans;
      if (ans == 100000)
        throw -1;
      P();
    }
    if (s[c] == 'v') {
      BACK();
      c++;
      ans++;
      if (nx == gx && ny == gy)
        throw ans;
      if (ans == 1000000)
        throw -1;
      P();
    }
    if (s[c] == '<') {
      TURN_L();
      c++;
      ans++;
      if (ans == 1000000)
        throw -1;
      P();
    }
    if (s[c] == '>') {
      TURN_R();
      c++;
      ans++;
      if (ans == 1000000)
        throw -1;
      P();
    }
    if (s[c] == '{') {
      WHILE();
    }
    if (s[c] == '[') {
      IF();
    }
  }
}

bool COND(string s) {
  bool NOT = false;
  if (s.size() == 2) {
    NOT = true;
    s = s.substr(1, 1);
  }

  if (s == "T")
    return true ^ NOT;
  if (s == "C") {
    int x = nx + dx[dir], y = ny + dy[dir];
    return (b[y][x] == '#') ^ NOT;
  }
  return (dm[s[0]] == dir) ^ NOT;
}

int main() {
  cin.tie(0);
  ios::sync_with_stdio(false);

  dm['E'] = 0;
  dm['S'] = 1;
  dm['W'] = 2;
  dm['N'] = 3;

  cin >> H >> W;
  for (int i = 0; i < H; i++) {
    cin >> b[i];
    for (int j = 0; j < W; j++) {
      if (b[i][j] == 'g') {
        gx = j, gy = i;
        b[i][j] = '.';
      }
      if (b[i][j] == 's') {
        nx = j, ny = i;
        b[i][j] = '.';
      }
    }
  }
  cin >> s;

  dir = dm['N'];
  try {
    P();
  } catch (int x) {
    cout << x << endl;
    return 0;
  };
  cout << -1 << endl;
}