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

#include <algorithm>
#include <iostream>
#include <map>
#include <string>
#include <vector>
using namespace std;

int w, h;

// 0:→, 1:↑, 2:←, 3:↓
int dx[4] = {+1, 0, -1, 0};
int dy[4] = {0, -1, 0, +1};

void debug(const vector<string> &s, int t) {
  char H[256] = {0};
  H['E'] = '>';
  H['W'] = '<';
  H['N'] = '^';
  H['S'] = 'v';
  H['X'] = 'X';
  H['.'] = '.';
  H['#'] = '#';

  cout << "time : " << t << endl;
  for (int y = 0; y < h; y++) {
    for (int x = 0; x < w; x++) {
      cout << H[s[y][x]];
    }
    cout << endl;
  }
  cout << endl;
}

// 位置 (px,py), 向き d, の人が空いているマスを探し, 最初に見つけた向きを返す.
// ないときは d を返す.
int search(const vector<string> &s, int px, int py, int d) {
  // 右, 前, 左, 後ろの順に調べる.
  int f[4] = {+3, 0, +1, +2};

  for (int i = 0; i < 4; i++) {
    int next_d = (d + f[i]) % 4;
    int mx = px + dx[next_d];
    int my = py + dy[next_d];

    if (mx < 0 || my < 0 || mx >= w || my >= h)
      continue;

    if (s[my][mx] == '.' || s[my][mx] == 'X') {
      return next_d;
    }
  }
  return d;
}

bool is_person(char c) {
  return (c == 'E' || c == 'W' || c == 'N' || c == 'S');
}

int main() {
  char H[256] = {0};
  H['E'] = 0;
  H['N'] = 1;
  H['W'] = 2;
  H['S'] = 3;
  H[0] = 'E';
  H[1] = 'N';
  H[2] = 'W';
  H[3] = 'S';

  while (cin >> w >> h, w || h) {
    vector<string> s(h);
    for (int y = 0; y < h; y++) {
      cin >> s[y];
    }
    // debug( s , 0 );
    //  N := 人の数
    int N = 0;
    // 人の数を数える.
    for (int y = 0; y < h; y++) {
      for (int x = 0; x < w; x++) {
        if (is_person(s[y][x]))
          N++;
      }
    }
    int ans = -1;
    for (int t = 1; t <= 180; t++) {
      for (int y = 0; y < h; y++) {
        for (int x = 0; x < w; x++) {
          // (x,y)が人だったら向きを変える
          if (is_person(s[y][x])) {
            int d = H[s[y][x]];
            int next_d = search(s, x, y, d);
            s[y][x] = H[next_d];
          }
        }
      }

      vector<string> s_ = s;
      bool cp[100][100] = {false};
      for (int y = 0; y < h; y++) {
        for (int x = 0; x < w; x++) {
          // (x,y) が移動可能なマス かつ まだ誰も移動していなければ調べる.
          if (s[y][x] == '.' || s[y][x] == 'X') {
            // 優先順位は マス(x,y) の右,上,左,下 の順.
            for (int i = 0; i < 4; i++) {
              int mx = x + dx[i];
              int my = y + dy[i];

              if (mx < 0 || my < 0 || mx >= w || my >= h)
                continue;

              // (mx,my) にいる人が (x,y) に移動する. (x,y) が出口'X'
              // なら人は消える.
              if (is_person(s[my][mx]) && abs(i - H[s[my][mx]]) == 2) {
                if (s[y][x] == 'X') {
                  s_[my][mx] = '.';
                  cp[my][mx] = true;
                  N--;
                } else {
                  s_[my][mx] = '.';
                  s_[y][x] = s[my][mx];
                  cp[y][x] = true;
                  cp[my][mx] = true;
                }
                break;
              }
            }
          }
          if (!cp[y][x])
            s_[y][x] = s[y][x];
        }
      }
      s = s_;
      // debug( s , t );
      if (N == 0) {
        ans = t;
        break;
      }
    }
    if (ans == -1) {
      cout << "NA" << endl;
    } else {
      cout << ans << endl;
    }
  }
}

Error: 0

Fixed submission:

#include <algorithm>
#include <iostream>
#include <map>
#include <string>
#include <vector>
using namespace std;

int w, h;

// 0:→, 1:↑, 2:←, 3:↓
int dx[4] = {+1, 0, -1, 0};
int dy[4] = {0, -1, 0, +1};

void debug(const vector<string> &s, int t) {
  char H[256] = {0};
  H['E'] = '>';
  H['W'] = '<';
  H['N'] = '^';
  H['S'] = 'v';
  H['X'] = 'X';
  H['.'] = '.';
  H['#'] = '#';

  cout << "time : " << t << endl;
  for (int y = 0; y < h; y++) {
    for (int x = 0; x < w; x++) {
      cout << H[s[y][x]];
    }
    cout << endl;
  }
  cout << endl;
}

// 位置 (px,py), 向き d, の人が空いているマスを探し, 最初に見つけた向きを返す.
// ないときは d を返す.
int search(const vector<string> &s, int px, int py, int d) {
  // 右, 前, 左, 後ろの順に調べる.
  int f[4] = {+3, 0, +1, +2};

  for (int i = 0; i < 4; i++) {
    int next_d = (d + f[i]) % 4;
    int mx = px + dx[next_d];
    int my = py + dy[next_d];
    if (s[my][mx] == '.' || s[my][mx] == 'X') {
      return next_d;
    }
  }
  return d;
}

bool is_person(char c) {
  return (c == 'E' || c == 'W' || c == 'N' || c == 'S');
}

int main() {
  char H[256] = {0};
  H['E'] = 0;
  H['N'] = 1;
  H['W'] = 2;
  H['S'] = 3;
  H[0] = 'E';
  H[1] = 'N';
  H[2] = 'W';
  H[3] = 'S';

  while (cin >> w >> h, w || h) {
    vector<string> s(h);
    for (int y = 0; y < h; y++) {
      cin >> s[y];
    }
    // debug( s , 0 );
    //  N := 人の数
    int N = 0;
    // 人の数を数える.
    for (int y = 0; y < h; y++) {
      for (int x = 0; x < w; x++) {
        if (is_person(s[y][x]))
          N++;
      }
    }
    int ans = -1;
    for (int t = 1; t <= 180; t++) {
      for (int y = 0; y < h; y++) {
        for (int x = 0; x < w; x++) {
          // (x,y)が人だったら向きを変える
          if (is_person(s[y][x])) {
            int d = H[s[y][x]];
            int next_d = search(s, x, y, d);
            s[y][x] = H[next_d];
          }
        }
      }
      // is_move[y][x] := (x,y) にすでに移動した人がいるので (x,y)
      // には移動できない.
      bool is_move[31][31] = {false};

      vector<string> s_(h);
      for (int y = 0; y < h; y++)
        s_[y] = s[y];
      bool cp[31][31] = {false};

      for (int y = 0; y < h; y++) {
        for (int x = 0; x < w; x++) {
          // (x,y)がまだ移動していない人で, 移動できるときは移動する.
          if (is_person(s[y][x]) && !is_move[y][x]) {
            int d = H[s[y][x]];
            int mx = x + dx[d];
            int my = y + dy[d];

            // 移動したいマス (mx,my) が通路 '.', 出口'X' 以外ならskipする.
            if (s[my][mx] != '.' && s[my][mx] != 'X')
              continue;

            // 移動したいマス(mx,my)に移動しようとする人全員を調べ,
            // 優先順位の一番高い人だけ移動させる. 優先順位は マス(mx,my)
            // の右,上,左,下 の順.
            for (int i = 0; i < 4; i++) {
              int nx = mx + dx[i];
              int ny = my + dy[i];

              // (nx,ny) にいる人が (mx,my) に移動する. (mx,my) が出口'X'
              // なら人は消える.
              if (is_person(s[ny][nx]) && abs(i - H[s[ny][nx]]) == 2) {
                if (s[my][mx] == 'X') {
                  s_[ny][nx] = '.';
                  cp[ny][nx] = true;
                  N--;
                } else {
                  s_[ny][nx] = '.';
                  s_[my][mx] = s[y][x];
                  cp[ny][nx] = true;
                  cp[my][mx] = true;
                }
                is_move[my][mx] = true;
                break;
              }
            }
          }
          if (!cp[y][x])
            s_[y][x] = s[y][x];
        }
      }
      s = s_;
      // debug( s , t );
      if (N == 0) {
        ans = t;
        break;
      }
    }
    if (ans == -1) {
      cout << "NA" << endl;
    } else {
      cout << ans << endl;
    }
  }
}