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

#include <bits/stdc++.h>
using namespace std;
#define MAX 55
#define INF 10000000

int dy[] = {-1, 0, 1, 0};
int dx[] = {0, 1, 0, -1};

int H, W;
char a[MAX][MAX];
string s;
int p, ans, len;
int py, px, ty, tx;
int dir, flg;

bool vd[4][MAX][MAX][1005];

int mem[1005];
int search(int x) {
  if (mem[x])
    return mem[x];
  char L = s[x], R;
  if (L == '{')
    R = '}';
  else if (L == '[')
    R = ']';
  else
    assert(0);

  int cnt = 1;
  for (int i = x + 1; i < len; i++) {
    if (s[i] == L)
      cnt++;
    if (s[i] == R)
      cnt--;
    if (cnt == 0)
      return mem[x] = i + 1;
  }
}

void func(char ch) {
  ans++;
  if (ch == '<')
    dir = (dir + 3) % 4;
  else if (ch == '>')
    dir = (dir + 1) % 4;
  else if (ch == '^' || ch == 'v') {
    int k = -1;
    if (ch == '^')
      k = 1;
    int ny = py + dy[dir] * k;
    int nx = px + dx[dir] * k;
    if (a[ny][nx] != '#')
      py = ny, px = nx;
    if (py == ty && px == tx && flg == 0) {
      cout << ans << endl;
      flg = 1;
      ans = INF;
    }
  }
}

bool check() {
  char ch = s[p++];
  if (ch == '~')
    return !check();
  if (ch == 'T')
    return true;
  if (ch == 'N')
    return (dir == 0);
  if (ch == 'E')
    return (dir == 1);
  if (ch == 'S')
    return (dir == 2);
  if (ch == 'W')
    return (dir == 3);
  int ny = py + dy[dir];
  int nx = px + dx[dir];
  return (a[ny][nx] == '#');
}

void solve();

void calc() {
  if (flg || ans >= INF)
    return;
  char ch = s[p++];
  if (ch == '[') {
    int np = search(p - 1);
    if (check())
      solve();
    if (flg || ans >= INF)
      return;
    p = np;
  } else if (ch == '{') {
    int b = p, np = search(p - 1);

    while (check()) {
      if (vd[dir][py][px][p - 1]) {
        ans = INF;
        return;
      }
      vd[dir][py][px][p - 1] = true;
      solve();
      if (flg || ans >= INF)
        return;
      p = b;
    }
    p = np;
  } else
    func(ch);
}

void solve() {
  while (p < len) {
    if (s[p] == '}')
      break;
    if (s[p] == ']')
      break;
    calc();
    if (flg || ans >= INF)
      return;
  }
}

int main() {
  cin >> H >> W;
  for (int i = 0; i < H; i++) {
    for (int j = 0; j < W; j++) {
      cin >> a[i][j];
      if (a[i][j] == 's') {
        a[i][j] = '.';
        py = i, px = j;
      } else if (a[i][j] == 'g') {
        a[i][j] = '.';
        ty = i, tx = j;
      }
    }
  }
  cin >> s;
  len = s.size();
  p = ans = dir = flg = 0;
  solve();
  if (!flg)
    cout << -1 << endl;
  return 0;
}

Error: TLE

Fixed submission:

#include <bits/stdc++.h>
using namespace std;
#define MAX 55
#define INF 10000000

int dy[] = {-1, 0, 1, 0};
int dx[] = {0, 1, 0, -1};

int H, W;
char a[MAX][MAX];
string s;
int p, ans, len;
int py, px, ty, tx;
int dir, flg;

bool vd[4][MAX][MAX][1005];

int mem[1005];
int search(int x) {
  if (mem[x])
    return mem[x];
  char L = s[x], R;
  if (L == '{')
    R = '}';
  else if (L == '[')
    R = ']';
  else
    assert(0);

  int cnt = 1;
  for (int i = x + 1; i < len; i++) {
    if (s[i] == L)
      cnt++;
    if (s[i] == R)
      cnt--;
    if (cnt == 0)
      return mem[x] = i + 1;
  }
}

void func(char ch) {
  ans++;
  if (ch == '<')
    dir = (dir + 3) % 4;
  else if (ch == '>')
    dir = (dir + 1) % 4;
  else if (ch == '^' || ch == 'v') {
    int k = -1;
    if (ch == '^')
      k = 1;
    int ny = py + dy[dir] * k;
    int nx = px + dx[dir] * k;
    if (a[ny][nx] != '#')
      py = ny, px = nx;
    if (py == ty && px == tx && flg == 0) {
      cout << ans << endl;
      flg = 1;
      ans = INF;
    }
  }
}

bool check() {
  char ch = s[p++];
  if (ch == '~')
    return !check();
  if (ch == 'T')
    return true;
  if (ch == 'N')
    return (dir == 0);
  if (ch == 'E')
    return (dir == 1);
  if (ch == 'S')
    return (dir == 2);
  if (ch == 'W')
    return (dir == 3);
  int ny = py + dy[dir];
  int nx = px + dx[dir];
  return (a[ny][nx] == '#');
}

void solve();

void calc() {
  if (flg || ans >= INF)
    return;
  char ch = s[p++];
  if (ch == '[') {
    int np = search(p - 1);
    if (check())
      solve();
    if (flg || ans >= INF)
      return;
    p = np;
  } else if (ch == '{') {
    int b = p, np = search(p - 1);
    if (vd[dir][py][px][p - 1]) {
      ans = INF;
      return;
    }
    vd[dir][py][px][p - 1] = true;
    while (check()) {
      solve();
      if (flg || ans >= INF)
        return;
      p = b;
    }
    p = np;
  } else
    func(ch);
}

void solve() {
  while (p < len) {
    if (s[p] == '}')
      break;
    if (s[p] == ']')
      break;
    calc();
    if (flg || ans >= INF)
      return;
  }
}

int main() {
  cin >> H >> W;
  for (int i = 0; i < H; i++) {
    for (int j = 0; j < W; j++) {
      cin >> a[i][j];
      if (a[i][j] == 's') {
        a[i][j] = '.';
        py = i, px = j;
      } else if (a[i][j] == 'g') {
        a[i][j] = '.';
        ty = i, tx = j;
      }
    }
  }
  cin >> s;
  len = s.size();
  p = ans = dir = flg = 0;
  solve();
  if (!flg)
    cout << -1 << endl;
  return 0;
}