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

#include <algorithm>
#include <queue>
#include <stdio.h>
using namespace std;

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

typedef pair<int, int> P;

int main(void) {
  int N, M;

  while (1) {
    scanf("%d %d", &N, &M);
    if (N == M && N == 0)
      break;

    char **s = new char *[N];

    for (int i = 0; i < N; i++) {
      s[i] = new char[M + 1];
    }
    for (int i = 0; i < N; i++)
      scanf("%s", s[i]);

    int count = 0;
    for (int i = 0; i < N; i++) {
      for (int j = 0; j < M; j++) {
        if (s[i][j] != 'a') {
          char a = s[i][j];
          s[i][j] = 'a';
          count++;
          queue<P> q;
          q.push(P(j, i));

          while (q.size()) {
            P p = q.front();
            q.pop();

            for (int k = 0; k < 4; k++) {
              int nx = dx[k] + p.first, ny = dy[k] + p.second;

              if (ny > -1 && nx > -1 && ny < N && nx < M && s[ny][nx] == a) {
                q.push(P(nx, ny));
                s[ny][nx] = 'a';
              }
            }
          }
        }
      }
    }
    printf("%d\\n", count);
  }
  return 0;
}

Error: 0

Fixed submission:

#include <queue>
#include <stdio.h>
using namespace std;

int main() {
  int map[101][101]; // 数値変換した果樹園のマップ
  char in[101];      // 入力文字列
  int y, x;          // 果樹園の大きさh,w
  int i, j, r;       // ループ用変数
  int ty[4] = {1, -1, 0, 0}, tx[4] = {0, 0, 1, -1}; // 四方向の移動量
  int temp;                                         // 作業用
  queue<pair<int, int>> que; // 幅優先探索用のキュー
  pair<int, int> P, NP; // pair型:任意の型２つをまとめて扱うことのできる型

  scanf("%d%d", &y, &x);

  while (y != 0 && x != 0) {
    // 初期化
    for (i = 0; i <= y + 1; i++) {
      map[0][i] = 0;
      map[x + 1][i] = 0;
    }
    for (i = 0; i <= x + 1; i++) {
      map[i][0] = 0;
      map[i][y + 1] = 0;
    }

    // 入力
    for (j = 1; j <= y; j++) {
      scanf("%s", in);
      // マップの数値化
      // しなくてもいいけど私はこうした方が分かり易いのでやる
      for (i = 1; i <= x; i++) {
        if (in[i - 1] == '#') {
          map[i][j] = -1;
        } else if (in[i - 1] == '*') {
          map[i][j] = -2;
        } else if (in[i - 1] == '@') {
          map[i][j] = -3;
        }
      }
    }

    // 連続した部分の探索
    int c = 0; // c:連続した区間の数
    for (j = 1; j <= y; j++) {
      for (i = 1; i <= x; i++) {
        if (map[i][j] < 0) {
          // printf("現在地:%d,%d\\n",i,j);
          c++;
          // 幅優先開始
          // P:現在地 NP:移動後の地点
          // temp:スタート地のマップの種類
          P.first = i;
          P.second = j;
          temp = map[P.first][P.second];
          map[P.first][P.second] = c;
          que.push(P);
          while (!que.empty()) {
            P = que.front();
            // 4方向を見る
            for (r = 0; r < 4; r++) {
              // もし現在地の果物の種類が移動後の位置の果物の種類と同じなら
              if (temp == map[P.first + tx[r]][P.second + ty[r]]) {
                NP.first = P.first + tx[r];
                NP.second = P.second + ty[r];
                map[NP.first][NP.second] = c;
                que.push(NP);
              }
            }
            que.pop();
          }
        }
      }
    }

    /*デバッグ用出力:mapの出力
    for(i = 0; i <= y+1; i++){
            for(j = 0; j <= x+1; j++){
                    printf("%2d",map[j][i]);
            }
            printf("\\n");
    }*/

    printf("%d\\n", c);

    scanf("%d%d", &y, &x);
  }

  return 0;
}