Problem p00223 (C++) — buggy submission, verdict: Memory Limit Exceeded

#include <iostream>
#include <map>
#include <queue>
using namespace std;

class Point2 {
public:
  int tx;
  int ty;
  int kx;
  int ky;
};

int mk(Point2 p) // キーを生成
{
  return (((p.tx - 1) * 50 + (p.ty - 1)) * 50 + (p.kx - 1)) * 50 + (p.ky - 1);
}

int main() {
  while (true) {
    int W, H;
    cin >> W >> H;

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

    Point2 p;
    cin >> p.tx >> p.ty;
    cin >> p.kx >> p.ky;

    int d[52][52];
    for (int y = 0; y <= H + 1; y++) {
      for (int x = 0; x <= W + 1; x++) {
        d[y][x] = 1; // 番兵
      }
    }

    for (int y = 1; y <= H; y++) {
      for (int x = 1; x <= W; x++) {
        cin >> d[y][x];
      }
    }

    queue<Point2> que; // キュー
    que.push(p);

    map<int, int> n; // マップ（時間）
    n[mk(p)] = 0;

    while (true) {
      if (que.empty()) { // 出会うことができない場合
        cout << "NA" << endl;
        break;
      }

      p = que.front();
      que.pop();

      if (n[mk(p)] >= 100) { // 100以上の時間を要する場合
        cout << "NA" << endl;
        break;
      }

      if (p.tx == p.kx && p.ty == p.ky) { // 2人が出会う
        cout << n[mk(p)] << endl;
        break;
      }

      Point2 q;

      // 東
      q = p;
      if (d[q.ty][q.tx + 1] == 0) {
        q.tx = q.tx + 1;
      }
      if (d[q.ky][q.kx - 1] == 0) {
        q.kx = q.kx - 1;
      }
      if (n.find(mk(q)) == n.end()) {
        que.push(q);
        n[mk(q)] = n[mk(p)] + 1;
      }

      // 西
      q = p;
      if (d[q.ty][q.tx - 1] == 0) {
        q.tx = q.tx - 1;
      }
      if (d[q.ky][q.kx + 1] == 0) {
        q.kx = q.kx + 1;
      }
      if (n.find(mk(q)) == n.end()) {
        que.push(q);
        n[mk(q)] = n[mk(p)] + 1;
      }

      // 南
      q = p;
      if (d[q.ty + 1][q.tx] == 0) {
        q.ty = q.ty + 1;
      }
      if (d[q.ky - 1][q.kx] == 0) {
        q.ky = q.ky - 1;
      }
      if (n.find(mk(q)) == n.end()) {
        que.push(q);
        n[mk(q)] = n[mk(p)] + 1;
      }

      // 北
      q = p;
      if (d[q.ty - 1][q.tx] == 0) {
        q.ty = q.ty - 1;
      }
      if (d[q.ky + 1][q.kx] == 0) {
        q.ky = q.ky + 1;
      }
      if (n.find(mk(q)) == n.end()) {
        que.push(q);
        n[mk(q)] = n[mk(p)] + 1;
      }
    }
  }

  return 0;
}


Error: MLE

Fixed submission:

#include <iostream>
#include <queue>
using namespace std;

int H, W;
class Point {
public:
  int tx; // タカユキの座標
  int ty;
  int kx; // カズユキの座標
  int ky;
  int d; // ターン回数
  void set(int a, int b, int c, int d) {
    tx = a;
    ty = b;
    kx = c;
    ky = d;
  }
};

int is_out_of_area(int y, int x) // 座標が範囲内か確認する関数
{
  return x < 1 || x > W || y < 1 || y > H;
}

int main() {
  bool F[52][52];         // 障害物
  bool D[52][52][52][52]; // 探索済みかの判定用

  Point p;
  int tx, ty, kx, ky;
  queue<Point> qa;
  while (1) {

    cin >> W >> H;
    if (W == 0 && H == 0)
      break;
    cin >> tx >> ty >> kx >> ky;

    for (int y = 0; y <= H + 1; y++) {
      for (int x = 0; x <= W + 1; x++) {
        F[y][x] = 1;
      }
    }
    for (int y = 1; y <= H; y++) {
      for (int x = 1; x <= W; x++) {
        int a;
        cin >> a;
        F[y][x] = a;
        for (int i = 1; i <= H; i++) {
          for (int j = 1; j <= W; j++) {
            D[y][x][i][j] = 1; // 1:未探索 , 0:探索済み
          }
        }
      }
    }

    p.set(tx, ty, kx, ky);
    p.d = 0;
    qa.push(p);

    while (1) {
      if (qa.empty()) {
        cout << "NA" << endl;
        break;
      }
      p = qa.front();
      qa.pop();
      if (p.d >= 100) {
        cout << "NA" << endl;
        break;
      }
      if (p.tx == p.kx && p.ty == p.ky) {
        cout << p.d << endl;
        break;
      }

      if (D[p.ty - 1][p.tx][p.ky + 1]
           [p.kx]) { // タカユキのy座標を-1, カズユキを+1
                     // 同様のif文が下に四つ続く
        int inc_ty = -1, inc_ky = 1;
        if (is_out_of_area(p.ty - 1, p.tx) ||
            F[p.ty - 1][p.tx]) { // 範囲外または障害物にあたったならば移動しない
          inc_ty = 0;
        }
        if (is_out_of_area(p.ky + 1, p.kx) ||
            F[p.ky + 1][p.kx]) { // 範囲外または障害物にあたったならば移動しない
          inc_ky = 0;
        }

        if (inc_ty ||
            inc_ky) { // どちらかが動ける状態であったならキューにプッシュ
          Point q;
          q.set(p.tx, p.ty + inc_ty, p.kx, p.ky + inc_ky);
          q.d = p.d + 1;
          qa.push(q);
          D[p.ty + inc_ty][p.tx][p.ky + inc_ky][p.kx] = 0;
        }
      }

      if (D[p.ty + 1][p.tx][p.ky - 1][p.kx]) {

        int inc_ty = 1, inc_ky = -1;
        if (is_out_of_area(p.ty + 1, p.tx) || F[p.ty + 1][p.tx]) {
          inc_ty = 0;
        }
        if (is_out_of_area(p.ky - 1, p.kx) || F[p.ky - 1][p.kx]) {
          inc_ky = 0;
        }

        if (inc_ty || inc_ky) {
          Point q;
          q.set(p.tx, p.ty + inc_ty, p.kx, p.ky + inc_ky);
          q.d = p.d + 1;
          qa.push(q);
          D[p.ty + inc_ty][p.tx][p.ky + inc_ky][p.kx] = 0;
        }
      }

      if (D[p.ty][p.tx - 1][p.ky][p.kx + 1]) {

        int inc_tx = -1, inc_kx = 1;
        if (is_out_of_area(p.ty, p.tx + inc_tx) || F[p.ty][p.tx + inc_tx]) {
          inc_tx = 0;
        }
        if (is_out_of_area(p.ky, p.kx + inc_kx) || F[p.ky][p.kx + inc_kx]) {
          inc_kx = 0;
        }

        if (inc_tx || inc_kx) {
          Point q;
          q.set(p.tx + inc_tx, p.ty, p.kx + inc_kx, p.ky);
          q.d = p.d + 1;
          qa.push(q);
          D[p.ty][p.tx + inc_tx][p.ky][p.kx + inc_kx] = 0;
        }
      }
      if (D[p.ty][p.tx + 1][p.ky][p.kx - 1]) {

        int inc_tx = 1, inc_kx = -1;
        if (is_out_of_area(p.ty, p.tx + inc_tx) || F[p.ty][p.tx + inc_tx]) {
          inc_tx = 0;
        }
        if (is_out_of_area(p.ky, p.kx + inc_kx) || F[p.ky][p.kx + inc_kx]) {
          inc_kx = 0;
        }

        if (inc_tx || inc_kx) {
          Point q;
          q.set(p.tx + inc_tx, p.ty, p.kx + inc_kx, p.ky);
          q.d = p.d + 1;
          qa.push(q);
          D[p.ty][p.tx + inc_tx][p.ky][p.kx + inc_kx] = 0;
        }
      }
    }
    while (!qa.empty()) {
      qa.pop();
    } // キューの残りカスを消去
  }
  return 0;
}