Problem p01752 (C++)

Buggy submission (status: Runtime Error):
#include <cmath>
#include <iostream>
#include <queue>
#define REP(i, a, n) for (int i = ((int)a); i < ((int)n); i++)
using namespace std;

struct state {
  int y, x, d, hy, hx, n;
  bool operator<(const state &s) const { return n > s.n; }
};

int N, M, D, SY, SX, GY, GX;
char S[52][52];
int dd[5] = {0, 1, 0, -1, 0};
bool visited[52][52][52][52][4];
bool step[52][52];

bool isin(int y, int x) { return 0 <= y && y < N + 2 && 0 <= x && x < M + 2; }

bool ok(int y, int x, int d, int hy, int hx) {
  if (S[y][x] == '#')
    return false;
  if (S[hy][hx] != '#')
    return false;
  bool f = false;
  if (y + dd[d] == hy && x + dd[d + 1] == hx)
    f = true;
  if (y + dd[d] + dd[(d + 1) % 4] == hy &&
      x + dd[d + 1] + dd[(d + 1) % 4 + 1] == hx)
    f = true;
  if (y + dd[(d + 1) % 4] == hy && x + dd[(d + 1) % 4 + 1] == hx)
    f = true;
  if (y + dd[(d + 1) % 4] + dd[(d + 2) % 4] == hy &&
      x + dd[(d + 1) % 4 + 1] + dd[(d + 2) % 4 + 1] == hx)
    f = true;
  return f;
}

int main(void) {
  cin >> N >> M;
  REP(i, 0, N + 2) REP(j, 0, N + 2) S[i][j] = '#';
  REP(i, 1, N + 1) REP(j, 1, M + 1) {
    cin >> S[i][j];
    if (S[i][j] == '>')
      SY = i, SX = j, D = 0;
    if (S[i][j] == 'v')
      SY = i, SX = j, D = 1;
    if (S[i][j] == '<')
      SY = i, SX = j, D = 2;
    if (S[i][j] == '^')
      SY = i, SX = j, D = 3;
    if (S[i][j] == 'G')
      GY = i, GX = j;
  }

  REP(i, 0, 52)
  REP(j, 0, 52) REP(k, 0, 52) REP(l, 0, 52) REP(m, 0, 4)
      visited[i][j][k][l][m] = false;
  REP(i, 0, 52) REP(j, 0, 52) step[i][j] = false;
  priority_queue<state> q;
  q.push((state){SY, SX, D, SY + dd[(D + 1) % 4], SX + dd[(D + 1) % 4 + 1], 1});

  int ans = -1;
  while (q.size()) {
    state s = q.top();
    q.pop();

    if (visited[s.y][s.x][s.hy][s.hx][s.d])
      continue;
    visited[s.y][s.x][s.hy][s.hx][s.d] = true;
    step[s.y][s.x] = true;

    if (s.y == GY && s.x == GX) {
      ans = s.n;
      break;
    }

    REP(i, -1, 2) {
      int nd = (s.d + i + 4) % 4;
      int ny = s.y + (i == 0 ? dd[nd] : 0);
      int nx = s.x + (i == 0 ? dd[nd + 1] : 0);
      int nhy = s.hy;
      int nhx = s.hx;
      int nn = s.n + (i == 0 && !step[ny][nx] ? 1 : 0);
      if (ok(ny, nx, nd, nhy, nhx)) {
        q.push((state){ny, nx, nd, nhy, nhx, nn});
      }
    }

    REP(i, -1, 2) REP(j, -1, 2) {
      if (i == 0 && j == 0)
        continue;
      int nd = s.d;
      int ny = s.y;
      int nx = s.x;
      int nhy = s.hy + i;
      int nhx = s.hx + j;
      int nn = s.n;
      if (isin(nhy, nhx) && ok(ny, nx, nd, nhy, nhx)) {
        q.push((state){ny, nx, nd, nhy, nhx, nn});
      }
    }
  }
  cout << ans << endl;

  return 0;
}

Fixed submission:
#include <cmath>
#include <iostream>
#include <queue>
#define REP(i, a, n) for (int i = ((int)a); i < ((int)n); i++)
using namespace std;

struct state {
  int y, x, d, hy, hx, n;
  bool operator<(const state &s) const { return n > s.n; }
};

int N, M, D, SY, SX, GY, GX;
char S[52][52];
int dd[5] = {0, 1, 0, -1, 0};
bool visited[52][52][52][52][4];
bool step[52][52];

bool isin(int y, int x) { return 0 <= y && y < N + 2 && 0 <= x && x < M + 2; }

bool ok(int y, int x, int d, int hy, int hx) {
  if (S[y][x] == '#')
    return false;
  if (S[hy][hx] != '#')
    return false;
  bool f = false;
  if (y + dd[d] == hy && x + dd[d + 1] == hx)
    f = true;
  if (y + dd[d] + dd[(d + 1) % 4] == hy &&
      x + dd[d + 1] + dd[(d + 1) % 4 + 1] == hx)
    f = true;
  if (y + dd[(d + 1) % 4] == hy && x + dd[(d + 1) % 4 + 1] == hx)
    f = true;
  if (y + dd[(d + 1) % 4] + dd[(d + 2) % 4] == hy &&
      x + dd[(d + 1) % 4 + 1] + dd[(d + 2) % 4 + 1] == hx)
    f = true;
  return f;
}

int main(void) {
  cin >> N >> M;
  REP(i, 0, N + 2) REP(j, 0, M + 2) S[i][j] = '#';
  REP(i, 1, N + 1) REP(j, 1, M + 1) {
    cin >> S[i][j];
    if (S[i][j] == '>')
      SY = i, SX = j, D = 0;
    if (S[i][j] == 'v')
      SY = i, SX = j, D = 1;
    if (S[i][j] == '<')
      SY = i, SX = j, D = 2;
    if (S[i][j] == '^')
      SY = i, SX = j, D = 3;
    if (S[i][j] == 'G')
      GY = i, GX = j;
  }

  REP(i, 0, 52)
  REP(j, 0, 52) REP(k, 0, 52) REP(l, 0, 52) REP(m, 0, 4)
      visited[i][j][k][l][m] = false;
  REP(i, 0, 52) REP(j, 0, 52) step[i][j] = false;
  priority_queue<state> q;
  q.push((state){SY, SX, D, SY + dd[(D + 1) % 4], SX + dd[(D + 1) % 4 + 1], 1});

  int ans = -1;
  while (q.size()) {
    state s = q.top();
    q.pop();

    if (visited[s.y][s.x][s.hy][s.hx][s.d])
      continue;
    visited[s.y][s.x][s.hy][s.hx][s.d] = true;
    step[s.y][s.x] = true;

    if (s.y == GY && s.x == GX) {
      ans = s.n;
      break;
    }

    REP(i, -1, 2) {
      int nd = (s.d + i + 4) % 4;
      int ny = s.y + (i == 0 ? dd[nd] : 0);
      int nx = s.x + (i == 0 ? dd[nd + 1] : 0);
      int nhy = s.hy;
      int nhx = s.hx;
      int nn = s.n + (i == 0 && !step[ny][nx] ? 1 : 0);
      if (ok(ny, nx, nd, nhy, nhx)) {
        q.push((state){ny, nx, nd, nhy, nhx, nn});
      }
    }

    REP(i, -1, 2) REP(j, -1, 2) {
      if (i == 0 && j == 0)
        continue;
      int nd = s.d;
      int ny = s.y;
      int nx = s.x;
      int nhy = s.hy + i;
      int nhx = s.hx + j;
      int nn = s.n;
      if (isin(nhy, nhx) && ok(ny, nx, nd, nhy, nhx)) {
        q.push((state){ny, nx, nd, nhy, nhx, nn});
      }
    }
  }
  cout << ans << endl;

  return 0;
}