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

#include "bits/stdc++.h"
#include <unordered_map>
#include <unordered_set>
#pragma warning(disable : 4996)
using namespace std;
using ld = long double;
template <class T> using Table = vector<vector<T>>;
const ld eps = 1e-9;

const int dx[4] = {-1, 0, 1, 0};
const int dy[4] = {0, 1, 0, -1};
vector<vector<int>> field;
int memo[50][50][1010][4];
string order;
int a = 0;
int nx, ny, way = 3;
int turn = 0;
int aans = 0;
bool getcond(bool valid) {
  bool rev = false;
  if (order[a] == '~') {
    a++;
    rev = true;
  }
  bool ans;
  switch (order[a]) {
  case 'N':
    ans = way == 3;
    break;
  case 'E':
    ans = way == 2;
    break;

  case 'S':
    ans = way == 1;
    break;

  case 'W':
    ans = way == 0;
    break;

  case 'C':
    ans = !field[ny + dy[way]][nx + dx[way]];
    break;

  case 'T':
    ans = true;
    break;
  default:
    assert(false);
  }
  a++;
  if (rev)
    ans = !ans;
  return ans;
}
void getmove(bool valid) {
  if (valid) {
    turn++;
    switch (order[a]) {
    case '^':
      if (field[ny + dy[way]][nx + dx[way]]) {
        ny += dy[way];
        nx += dx[way];
      }
      break;
    case 'v':
      if (field[ny - dy[way]][nx - dx[way]]) {
        ny -= dy[way];
        nx -= dx[way];
      }
      break;
    case '<':
      way = (way + 1) % 4;
      break;
    case '>':
      way = (way + 3) % 4;
      break;
    default:
      assert(false);
    }
    // cout << "y:" << ny << " x:" << nx << "way:" << way << endl;
    a++;
    if (field[ny][nx] == 2) {
      aans = turn;
      throw(false);
    } else {
      return;
    }
  }
  a++;
  return;
}
void getpro(bool valid);
void getif(bool valid) {
  assert(order[a] == '[');
  a++;
  bool ok = getcond(valid);
  getpro(ok & valid);
  assert(order[a] == ']');
  a++;
  return;
}
void getwhile(bool valid) {
  assert(order[a] == '{');
  a++;
  int pre = a;
  while (1) {
    if (valid) {
      if (memo[ny][nx][a][way] <= turn) {
        aans = -1;
        throw(false);
      } else {
        memo[ny][nx][a][way] = turn;
      }
    }

    a = pre;
    bool ok = getcond(valid);
    getpro(valid & ok);
    if (!ok)
      break;
    if (!valid)
      break;
  }
  assert(order[a] == '}');
  a++;
}
void getexpr(bool valid) {
  if (order[a] == '[') {
    getif(valid);
  } else if (order[a] == '{') {
    getwhile(valid);
  } else {
    getmove(valid);
  }
}
void getpro(bool valid) {
  while (1) {
    if (order[a] == ']' || order[a] == '}')
      break;
    getexpr(valid);
    if (a == order.size())
      break;
  }
}
int main() {
  for (int i = 0; i < 50; ++i) {
    for (int j = 0; j < 50; ++j) {
      for (int t = 0; t < 1010; ++t) {
        for (int w = 0; w < 4; ++w) {

          memo[i][j][t][w] = 1e9;
        }
      }
    }
  }
  int H, W;
  cin >> H >> W;
  field.resize(H);
  for (int i = 0; i < H; ++i) {
    string st;
    cin >> st;
    field[i].resize(W);
    for (int j = 0; j < W; ++j) {
      if (st[j] == '#') {
        field[i][j] = 0;
      } else if (st[j] == '.') {
        field[i][j] = 1;
      } else if (st[j] == 's') {
        field[i][j] = 1;
        nx = j;
        ny = i;
      } else {
        assert(st[j] == 'g');
        field[i][j] = 2;
      }
    }
  }
  cin >> order;
  try {
    getpro(true);
    if (aans == 0)
      aans = -1;
  } catch (...) {
    if (aans == 0) {
      aans = -1;
    }
  }
  cout << aans << endl;
  return 0;
}

Error: TLE

Fixed submission:

#include "bits/stdc++.h"
#include <unordered_map>
#include <unordered_set>
#pragma warning(disable : 4996)
using namespace std;
using ld = long double;
template <class T> using Table = vector<vector<T>>;
const ld eps = 1e-9;

const int dx[4] = {-1, 0, 1, 0};
const int dy[4] = {0, 1, 0, -1};
vector<vector<int>> field;
int memo[50][50][1010][4];
string order;
int a = 0;
int nx, ny, way = 3;
int turn = 0;
int aans = 0;
bool getcond(bool valid) {
  bool rev = false;
  if (order[a] == '~') {
    a++;
    rev = true;
  }
  bool ans;
  switch (order[a]) {
  case 'N':
    ans = way == 3;
    break;
  case 'E':
    ans = way == 0;
    break;

  case 'S':
    ans = way == 1;
    break;

  case 'W':
    ans = way == 2;
    break;

  case 'C':
    ans = !field[ny + dy[way]][nx + dx[way]];
    break;

  case 'T':
    ans = true;
    break;
  default:
    assert(false);
  }
  a++;
  if (rev)
    ans = !ans;
  return ans;
}
void getmove(bool valid) {
  if (valid) {
    turn++;
    switch (order[a]) {
    case '^':
      if (field[ny + dy[way]][nx + dx[way]]) {
        ny += dy[way];
        nx += dx[way];
      }
      break;
    case 'v':
      if (field[ny - dy[way]][nx - dx[way]]) {
        ny -= dy[way];
        nx -= dx[way];
      }
      break;
    case '<':
      way = (way + 1) % 4;
      break;
    case '>':
      way = (way + 3) % 4;
      break;
    default:
      assert(false);
    }
    a++;
    if (memo[ny][nx][a][way] < turn) {
      aans = -1;
      throw(false);
    } else {
      memo[ny][nx][a][way] = turn;
      if (field[ny][nx] == 2) {
        aans = turn;
        throw(false);
      } else {
        return;
      }
    }
  }
  a++;
  return;
}
void getpro(bool valid);
void getif(bool valid) {
  assert(order[a] == '[');
  a++;
  bool ok = getcond(valid);
  getpro(ok);
  assert(order[a] == ']');
  a++;
  return;
}
void getwhile(bool valid) {
  assert(order[a] == '{');
  a++;
  int pre = a;
  while (1) {
    a = pre;
    bool ok = getcond(valid);
    getpro(ok);
    if (!ok)
      break;
    if (!valid)
      break;
  }
  assert(order[a] == '}');
  a++;
}
void getexpr(bool valid) {
  if (order[a] == '[') {
    getif(valid);
  } else if (order[a] == '{') {
    getwhile(valid);
  } else {
    getmove(valid);
  }
}
void getpro(bool valid) {
  while (1) {
    if (order[a] == ']' || order[a] == '}')
      break;
    getexpr(valid);
    if (a == order.size())
      break;
  }
}
int main() {
  for (int i = 0; i < 50; ++i) {
    for (int j = 0; j < 50; ++j) {
      for (int t = 0; t < 1010; ++t) {
        for (int w = 0; w < 4; ++w) {

          memo[i][j][t][w] = 1e9;
        }
      }
    }
  }
  int H, W;
  cin >> H >> W;
  field.resize(H);
  for (int i = 0; i < H; ++i) {
    string st;
    cin >> st;
    field[i].resize(W);
    for (int j = 0; j < W; ++j) {
      if (st[j] == '#') {
        field[i][j] = 0;
      } else if (st[j] == '.') {
        field[i][j] = 1;
      } else if (st[j] == 's') {
        field[i][j] = 1;
        nx = j;
        ny = i;
      } else {
        assert(st[j] == 'g');
        field[i][j] = 2;
      }
    }
  }
  cin >> order;
  try {
    getpro(true);
    if (aans == 0)
      aans = -1;
  } catch (...) {
    if (aans == 0) {
      aans = -1;
    }
  }
  cout << aans << endl;
  return 0;
}