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

#include <iostream>
#include <set>
#include <string>
#include <vector>

#define MAX 40

#define WALL '#'
#define EXIT 'X'
#define TILE '.'

#define EAST 0
#define NORTH 1
#define WEST 2
#define SOUTH 3
#define MAXDIR 4

#define rep(i, b, n) for (int i = (b); i < (n); ++i)

int condir[128];
char revdir[4];
const int di[] = {0, -1, 0, 1};
const int dj[] = {1, 0, -1, 0};

using namespace std;

typedef pair<int, int> pi;

struct Squares {
  int H, W;
  Squares() : H(0), W(0) {}
  Squares(int H, int W) : H(H), W(W) {}
  char D[MAX][MAX];

  bool isInside(int i, int j) const {
    return 0 <= i && i < H && 0 <= j && j < W;
  }
  bool isEmpty(int i, int j) const {
    return D[i][j] == EXIT || D[i][j] == TILE;
  }
  bool isPerson(int i, int j) const {
    return D[i][j] == 'E' || D[i][j] == 'N' || D[i][j] == 'W' || D[i][j] == 'S';
  }
  void escapersStage1() {
    rep(i, 0, H) {
      rep(j, 0, W) {
        if (isPerson(i, j)) {
          int initk = condir[D[i][j]] - 1 + MAXDIR;
          int endk = initk + MAXDIR;
          for (int k = initk; k < endk; ++k) {
            int ti = i + di[k % MAXDIR];
            int tj = j + dj[k % MAXDIR];
            if (isInside(ti, tj)) {
              if (isEmpty(ti, tj)) {
                D[i][j] = revdir[k % MAXDIR];
                break;
              }
            }
          }
        }
      }
    }
  }

  pi getfront(int i, int j, int dir) {
    return make_pair(i + di[dir], j + dj[dir]);
  }

  void escapersStage2() {
    char newD[MAX][MAX];
    rep(i, 0, MAX) rep(j, 0, MAX) newD[i][j] = -1;
    rep(i, 0, H) {
      rep(j, 0, W) {
        if (isEmpty(i, j)) {
          for (int k = 0; k < MAXDIR; ++k) {
            int ti = i + di[k];
            int tj = j + dj[k];
            if (isInside(ti, tj)) {
              pi pfront = getfront(ti, tj, condir[D[ti][tj]]);
              if (isPerson(ti, tj) && pfront.first == i && pfront.second == j) {
                newD[i][j] = D[ti][tj];
                newD[ti][tj] = TILE;
                if (D[i][j] == EXIT)
                  newD[i][j] = EXIT;
                break;
              }
            }
          }
        }
      }
    }
    rep(i, 0, H) rep(j, 0, W) {
      if (newD[i][j] == -1)
        newD[i][j] = D[i][j];
    }
    rep(i, 0, H) rep(j, 0, W) { D[i][j] = newD[i][j]; }
  }
  int getRemainedPersons() {
    int ret = 0;
    rep(i, 0, H) rep(j, 0, W) {
      if (isPerson(i, j))
        ++ret;
    }
    return ret;
  }
  void Print() {
    cout << " THE SQUARES COND : " << endl;
    rep(i, 0, H) {
      rep(j, 0, W) { cout << D[i][j]; }
      cout << endl;
    }
  }
};

int main() {
  revdir[EAST] = 'E';
  revdir[NORTH] = 'N';
  revdir[WEST] = 'W';
  revdir[SOUTH] = 'S';
  condir[(int)'E'] = EAST;
  condir[(int)'N'] = NORTH;
  condir[(int)'W'] = WEST;
  condir[(int)'S'] = SOUTH;

  while (true) {
    int W, H;
    int t = 0;
    cin >> W >> H;

    if (W == 0 && H == 0)
      break;

    Squares sq(H, W);
    rep(i, 0, H) {
      rep(j, 0, W) { cin >> sq.D[i][j]; }
    }

    while (t <= 180 && sq.getRemainedPersons() > 0) {
      // sq.Print();
      sq.escapersStage1();
      sq.escapersStage2();
      ++t;
    }

    if (t > 180)
      cout << "NA" << endl;
    else
      cout << t << endl;
  }
  return 0;
}

Error: 0

Fixed submission:

#include <iostream>
#include <set>
#include <string>
#include <vector>

#define MAX 40

#define WALL '#'
#define EXIT 'X'
#define TILE '.'

#define EAST 0
#define NORTH 1
#define WEST 2
#define SOUTH 3
#define MAXDIR 4

#define rep(i, b, n) for (int i = (b); i < (n); ++i)

int condir[128];
char revdir[4];
const int di[] = {0, -1, 0, 1};
const int dj[] = {1, 0, -1, 0};

using namespace std;

typedef pair<int, int> pi;

struct Squares {
  int H, W;
  Squares() : H(0), W(0) {}
  Squares(int H, int W) : H(H), W(W) {}
  char D[MAX][MAX];

  bool isEmpty(int i, int j) const {
    return D[i][j] == EXIT || D[i][j] == TILE;
  }
  bool isPerson(int i, int j) const {
    return D[i][j] == 'E' || D[i][j] == 'N' || D[i][j] == 'W' || D[i][j] == 'S';
  }
  void escapersStage1() {
    rep(i, 0, H) {
      rep(j, 0, W) {
        if (isPerson(i, j)) {
          int initk = condir[D[i][j]] - 1 + MAXDIR;
          int endk = initk + MAXDIR;
          for (int k = initk; k < endk; ++k) {
            if (isEmpty(i + di[k % MAXDIR], j + dj[k % MAXDIR])) {
              D[i][j] = revdir[k % MAXDIR];
              break;
            }
          }
        }
      }
    }
  }

  pi getfront(int i, int j, int dir) {
    return make_pair(i + di[dir], j + dj[dir]);
  }

  void escapersStage2() {
    char newD[MAX][MAX];
    rep(i, 0, MAX) rep(j, 0, MAX) newD[i][j] = -1;
    rep(i, 0, H) {
      rep(j, 0, W) {
        if (isEmpty(i, j)) {
          for (int k = 0; k < MAXDIR; ++k) {
            pi pfront =
                getfront(i + di[k], j + dj[k], condir[D[i + di[k]][j + dj[k]]]);
            if (isPerson(i + di[k], j + dj[k]) && pfront.first == i &&
                pfront.second == j) {
              newD[i][j] = D[i + di[k]][j + dj[k]];
              newD[i + di[k]][j + dj[k]] = TILE;
              if (D[i][j] == EXIT)
                newD[i][j] = EXIT;
              break;
            }
          }
        }
      }
    }
    rep(i, 0, H) rep(j, 0, W) {
      if (newD[i][j] == -1)
        newD[i][j] = D[i][j];
    }
    rep(i, 0, H) rep(j, 0, W) { D[i][j] = newD[i][j]; }
  }
  int getRemainedPersons() {
    int ret = 0;
    rep(i, 0, H) rep(j, 0, W) {
      if (isPerson(i, j))
        ++ret;
    }
    return ret;
  }
  void Print() {
    cout << " THE SQUARES COND : " << endl;
    rep(i, 0, H) {
      rep(j, 0, W) { cout << D[i][j]; }
      cout << endl;
    }
  }
};

int main() {
  revdir[EAST] = 'E';
  revdir[NORTH] = 'N';
  revdir[WEST] = 'W';
  revdir[SOUTH] = 'S';
  condir[(int)'E'] = EAST;
  condir[(int)'N'] = NORTH;
  condir[(int)'W'] = WEST;
  condir[(int)'S'] = SOUTH;

  while (true) {
    int W, H;
    int t = 0;
    cin >> W >> H;

    if (W == 0 && H == 0)
      break;

    Squares sq(H, W);
    rep(i, 0, H) {
      rep(j, 0, W) { cin >> sq.D[i][j]; }
    }

    while (t <= 180 && sq.getRemainedPersons() > 0) {
      // sq.Print();
      sq.escapersStage1();
      sq.escapersStage2();
      ++t;
    }

    if (t > 180)
      cout << "NA" << endl;
    else
      cout << t << endl;
  }
  return 0;
}