Problem p00210 (C++) — buggy submission, verdict: Runtime Error

#include <algorithm>
#include <cassert>
#include <cmath>
#include <iostream>
#include <map>
#include <queue>
#include <vector>
#define REP(i, s, n) for (int i = s; i < n; i++)
#define rep(i, n) REP(i, 0, n)
#define inf (1 << 28)
#define MAX 35
#define next(a, b) ((((a + 3) % 4) + b) % 4)
using namespace std;

struct P {
  int x, y, dir;
  P(int x = inf, int y = inf, int dir = inf) : x(x), y(y), dir(dir) {}
};

int dx[] = {+1, +0, -1, +0};
int dy[] = {+0, -1, +0, +1};
int H, W;
char G[MAX][MAX];
int I[MAX][MAX];
int D[MAX][MAX];
int Next[MAX][MAX];
string DIR = "ENWS";
vector<P> vec;

bool Finish() {
  rep(i, vec.size()) {
    if (G[vec[i].y][vec[i].x] != 'X')
      return false;
  }
  return true;
}

void print() {
  cout << "print- ---" << endl;
  rep(i, H) {
    rep(j, W) { cout << G[i][j]; }
    cout << endl;
  }
  cout << endl;
}
void print2() {
  cout << "2print- ---" << endl;
  rep(i, H) {
    rep(j, W) { cout << D[i][j]; }
    cout << endl;
  }
  cout << endl;
}

void decide() {
  rep(i, vec.size()) {
    int x = vec[i].x;
    int y = vec[i].y;
    if (G[y][x] == 'X')
      continue;
    int dir = vec[i].dir;
    Next[y][x] = inf;
    rep(j, 4) {
      int nx = x + dx[next(dir, j)];
      int ny = y + dy[next(dir, j)];
      if (!(0 <= nx && nx < W && 0 <= ny && ny < H))
        continue;
      if (!(G[ny][nx] == '.' || G[ny][nx] == 'X'))
        continue;
      vec[i].dir = next(dir, j);
      D[ny][nx]++;
      break;
    }
  }
}

bool check(int x, int y, int cx, int cy) {
  rep(i, 4) {
    int nx = cx + dx[i];
    int ny = cy + dy[i];
    if (!(0 <= nx && nx < W && 0 <= ny && ny < H))
      continue;
    if (G[ny][nx] == '.' || G[ny][nx] == 'X' || G[ny][nx] == '#')
      continue;
    return nx == x && ny == y;
  }
  assert(false);
}

void move() {
  rep(i, vec.size()) {
    int x = vec[i].x;
    int y = vec[i].y;
    if (G[y][x] == 'X')
      continue;

    int dir = vec[i].dir;

    int nx = x + dx[dir];
    int ny = y + dy[dir];
    if (!(0 <= nx && nx < W && 0 <= ny && ny < H))
      continue;
    if (!(G[ny][nx] == '.' || G[ny][nx] == 'X'))
      continue;
    if (D[ny][nx] == 0)
      continue;
    if (D[ny][nx] == 0) {
      cout << i << " is out: " << x << "," << y << " -> " << nx << "," << ny
           << endl;
      print();
      print2();
    }
    if (D[ny][nx] == 0)
      continue;
    // assert(D[ny][nx]);
    if (D[ny][nx] == 1 || (D[ny][nx] >= 2 && check(x, y, nx, ny))) {
      D[ny][nx] = 0;
      G[y][x] = '.';
      vec[i].x = nx, vec[i].y = ny;
      if (G[ny][nx] != 'X')
        G[ny][nx] = DIR[dir];
    }
  }
  rep(i, H) rep(j, W) D[i][j] = 0;
}

int main() {
  while (cin >> W >> H, W | H) {
    vec.clear();
    rep(i, H) rep(j, W) {
      cin >> G[i][j];
      I[i][j] = -inf;
      if (!(G[i][j] == '.' || G[i][j] == '#' || G[i][j] == 'X')) {
        char c = G[i][j];
        int dir =
            (c == 'E'
                 ? 0
                 : (c == 'N' ? 1 : (c == 'W' ? 2 : (c == 'S' ? 3 : -inf))));
        vec.push_back(P(j, i, dir));
      }
    }

    if (vec.empty()) {
      cout << 0 << endl;
      continue;
    }

    rep(phase, 180) {
      // print();
      decide();

      move();

      if (Finish()) {
        cout << phase + 1 << endl;
        goto Fin;
      }
    }
    cout << "NA" << endl;
  Fin:;
  }

  return 0;
}

Error: 0

Fixed submission:

#include <algorithm>
#include <cassert>
#include <cmath>
#include <iostream>
#include <map>
#include <queue>
#include <vector>
#define REP(i, s, n) for (int i = s; i < n; i++)
#define rep(i, n) REP(i, 0, n)
#define inf (1 << 28)
#define MAX 35
#define next(a, b) ((((a + 3) % 4) + b) % 4)
using namespace std;

struct P {
  int x, y, dir;
  P(int x = inf, int y = inf, int dir = inf) : x(x), y(y), dir(dir) {}
};

int dx[] = {+1, +0, -1, +0};
int dy[] = {+0, -1, +0, +1};
int H, W;
char G[MAX][MAX];
int I[MAX][MAX];
int D[MAX][MAX];
int Next[MAX][MAX];
string DIR = "ENWS";
vector<P> vec;

bool Finish() {
  rep(i, vec.size()) {
    if (G[vec[i].y][vec[i].x] != 'X')
      return false;
  }
  return true;
}

void print() {
  cout << "print- ---" << endl;
  rep(i, H) {
    rep(j, W) { cout << G[i][j]; }
    cout << endl;
  }
  cout << endl;
}
void print2() {
  cout << "2print- ---" << endl;
  rep(i, H) {
    rep(j, W) { cout << D[i][j]; }
    cout << endl;
  }
  cout << endl;
}

void decide() {
  rep(i, vec.size()) {
    int x = vec[i].x;
    int y = vec[i].y;
    if (G[y][x] == 'X')
      continue;
    int dir = vec[i].dir;
    rep(j, 4) {
      int nx = x + dx[next(dir, j)];
      int ny = y + dy[next(dir, j)];
      if (!(0 <= nx && nx < W && 0 <= ny && ny < H))
        continue;
      if (!(G[ny][nx] == '.' || G[ny][nx] == 'X'))
        continue;
      Next[y][x] = next(dir, j);
      D[ny][nx]++;
      break;
    }
  }
}

bool check(int x, int y, int cx, int cy) {
  rep(i, 4) {
    int nx = cx + dx[i];
    int ny = cy + dy[i];
    if (!(0 <= nx && nx < W && 0 <= ny && ny < H))
      continue;
    if (G[ny][nx] == '.' || G[ny][nx] == 'X' || G[ny][nx] == '#')
      continue;
    return nx == x && ny == y;
  }
  assert(false);
}

void move() {
  rep(i, vec.size()) {
    int x = vec[i].x;
    int y = vec[i].y;
    if (G[y][x] == 'X')
      continue;
    int dir = vec[i].dir;

    int nx = x + dx[Next[y][x]];
    int ny = y + dy[Next[y][x]];
    if (!(0 <= nx && nx < W && 0 <= ny && ny < H))
      continue;
    if (!(G[ny][nx] == '.' || G[ny][nx] == 'X'))
      continue;
    if (D[ny][nx] == 0) {
      cout << i << " is out: " << x << "," << y << " -> " << nx << "," << ny
           << endl;
      print();
      print2();
    }
    assert(D[ny][nx]);
    if (D[ny][nx] == 1 || (D[ny][nx] >= 2 && check(x, y, nx, ny))) {
      G[y][x] = '.';
      vec[i].x = nx, vec[i].y = ny, vec[i].dir = Next[y][x];
      if (G[ny][nx] != 'X')
        G[ny][nx] = DIR[Next[y][x]];
    }
  }
  rep(i, H) rep(j, W) D[i][j] = 0;
}

int main() {
  while (cin >> W >> H, W | H) {
    vec.clear();
    rep(i, H) rep(j, W) {
      cin >> G[i][j];
      I[i][j] = -inf;
      if (!(G[i][j] == '.' || G[i][j] == '#' || G[i][j] == 'X')) {
        char c = G[i][j];
        int dir =
            (c == 'E'
                 ? 0
                 : (c == 'N' ? 1 : (c == 'W' ? 2 : (c == 'S' ? 3 : -inf))));
        vec.push_back(P(j, i, dir));
      }
    }

    if (vec.empty()) {
      cout << 0 << endl;
      continue;
    }

    rep(phase, 180) {
      // print();
      decide();

      move();

      if (Finish()) {
        cout << phase + 1 << endl;
        goto Fin;
      }
    }
    cout << "NA" << endl;
  Fin:;
  }

  return 0;
}