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

#include <algorithm>
#include <cstring>
#include <iostream>
#include <vector>
using namespace std;
const int inf = 1e9;
int dx[4] = {0, -1, 0, 1};
int dy[4] = {-1, 0, 1, 0};

int h, w;
int y, x, d = 0, ans = 0;
char field[50][50];
bool used[50][50][4][1001];
string str;
bool check_condition(int p) {
  bool t = true;
  bool f = false;
  if (str[p] == '~') {
    swap(t, f);
    p++;
  }
  switch (str[p]) {
  case 'N':
    return d == 0 ? t : f;
  case 'W':
    return d == 1 ? t : f;
  case 'S':
    return d == 2 ? t : f;
  case 'E':
    return d == 3 ? t : f;
  case 'C':
    return (field[y + dy[d]][x + dx[d]] == '#') ? t : f;
  default:
    return t;
  }
}
int getnext(int p) {
  if (str[p] == '~')
    return p + 2;
  if (str[p] != '{' && str[p] != '[')
    return p + 1;
  int depth = 1;
  while (depth > 0) {
    p++;
    if (str[p] == '{' || str[p] == '[')
      depth++;
    if (str[p] == '}' || str[p] == ']')
      depth--;
  }
  return p + 1;
}
int program_if(int p);
int program_while(int p);
int execute(int p) {
  while (1) {
    if (used[y][x][d][p])
      return -1;
    used[y][x][d][p] = true;
    if (field[y][x] == 'g')
      return 1;
    if (p >= (int)str.length() || str[p] == '}' || str[p] == ']')
      break;
    if (str[p] == '[') {
      int res = program_if(p);
      if (res != 0)
        return res;
    } else if (str[p] == '{') {
      int res = program_while(p);
      if (res != 0)
        return res;
    } else {
      if (str[p] == '^' && field[y + dy[d]][x + dx[d]] != '#') {
        y += dy[d];
        x += dx[d];
      }
      if (str[p] == 'v' &&
          field[y + dy[(d + 2) % 4]][x + dx[(d + 2) % 4]] != '#') {
        y += dy[(d + 2) % 4];
        x += dx[(d + 2) % 4];
      }
      if (str[p] == '<')
        d = (d + 1) % 4;
      if (str[p] == '>')
        d = (d + 3) % 4;
      ans++;
    }
    p = getnext(p);
  }
  return 0;
}

int program_if(int p) {
  if (check_condition(p + 1)) {
    return execute(getnext(p + 1));
  }
  return 0;
}
int program_while(int p) {
  while (check_condition(p + 1)) {
    int res = execute(getnext(p + 1));
    if (res != 0)
      return res;
  }
  return 0;
}

int main() {
  cin >> h >> w;
  for (int i = 0; i < h; i++) {
    for (int j = 0; j < w; j++) {
      cin >> field[i][j];
      if (field[i][j] == 's') {
        y = i;
        x = j;
      }
    }
  }
  cin >> str;
  memset(used, 0, sizeof(used));
  if (execute(0) == 1) {
    cout << ans << endl;
  } else {
    cout << -1 << endl;
  }
  return 0;
}


Error: TLE

Fixed submission:

#include <algorithm>
#include <cstring>
#include <iostream>
#include <vector>
using namespace std;
const int inf = 1e9;
int dx[4] = {0, -1, 0, 1};
int dy[4] = {-1, 0, 1, 0};

int h, w;
int y, x, d = 0, ans = 0;
char field[50][50];
bool used[50][50][4][1000];
string str;
bool check_condition(int p) {
  bool t = true;
  bool f = false;
  if (str[p] == '~') {
    swap(t, f);
    p++;
  }
  switch (str[p]) {
  case 'N':
    return d == 0 ? t : f;
  case 'W':
    return d == 1 ? t : f;
  case 'S':
    return d == 2 ? t : f;
  case 'E':
    return d == 3 ? t : f;
  case 'C':
    return (field[y + dy[d]][x + dx[d]] == '#') ? t : f;
  default:
    return t;
  }
}
int getnext(int p) {
  if (str[p] == '~')
    return p + 2;
  if (str[p] != '{' && str[p] != '[')
    return p + 1;
  int depth = 1;
  while (depth > 0) {
    p++;
    if (str[p] == '{' || str[p] == '[')
      depth++;
    if (str[p] == '}' || str[p] == ']')
      depth--;
  }
  return p + 1;
}
int program_if(int p);
int program_while(int p);
int execute(int p) {
  while (p < (int)str.length() && str[p] != '}' && str[p] != ']') {
    if (used[y][x][d][p])
      return -1;
    used[y][x][d][p] = true;
    if (field[y][x] == 'g')
      return 1;
    if (str[p] == '[') {
      int res = program_if(p);
      if (res != 0)
        return res;
    } else if (str[p] == '{') {
      int res = program_while(p);
      if (res != 0)
        return res;
    } else {
      if (str[p] == '^' && field[y + dy[d]][x + dx[d]] != '#') {
        y += dy[d];
        x += dx[d];
      }
      if (str[p] == 'v' && field[y + dy[d]][x + dx[d]] != '#') {
        y += dy[(d + 2) % 4];
        x += dx[(d + 2) % 4];
      }
      if (str[p] == '<')
        d = (d + 1) % 4;
      if (str[p] == '>')
        d = (d + 3) % 4;
      ans++;
    }
    p = getnext(p);
  }
  return 0;
}

int program_if(int p) {
  if (check_condition(p + 1)) {
    return execute(getnext(p + 1));
  }
  return 0;
}
int program_while(int p) {
  while (check_condition(p + 1)) {
    int res = execute(getnext(p + 1));
    if (res != 0)
      return res;
  }
  return 0;
}

int main() {
  cin >> h >> w;
  for (int i = 0; i < h; i++) {
    for (int j = 0; j < w; j++) {
      cin >> field[i][j];
      if (field[i][j] == 's') {
        y = i;
        x = j;
      }
    }
  }
  cin >> str;
  memset(used, 0, sizeof(used));
  if (execute(0) == 1) {
    cout << ans << endl;
  } else {
    cout << -1 << endl;
  }
  return 0;
}