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

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

class State {
public:
  int x1, y1, x2, y2, cost;

  State(int tx1, int ty1, int tx2, int ty2, int tcost) {
    x1 = tx1;
    y1 = ty1;
    x2 = tx2;
    y2 = ty2;
    cost = tcost;
  }
};

int w, h;
bool t[52][52];
bool closed[52][52][52][52];

int dx1[] = {-1, 1, 0, 0};
int dx2[] = {1, -1, 0, 0};
int dy1[] = {0, 0, 1, -1};
int dy2[] = {0, 0, -1, 1};

int main(void) {
  while (cin >> w >> h && (w || h)) {
    int x1, y1, x2, y2;
    cin >> x1 >> y1 >> x2 >> y2;
    x1--;
    y1--;
    x2--;
    y2--;

    for (int i = 0; i < h; i++) {
      for (int j = 0; j < w; j++) {
        cin >> t[i][j];
      }
    }

    int ans = -1;
    queue<State> open;

    memset(closed, 0, sizeof(closed));
    closed[x1][y1][x2][y2] = true;
    open.push(State(x1, y1, x2, y2, 0));

    while (!open.empty()) {
      State st = open.front();
      open.pop();
      if (st.cost >= 100)
        break;

      if (st.x1 == st.x2 && st.y1 == st.y2) {
        ans = st.cost;
        break;
      }

      for (int i = 0; i < 4; i++) {
        int nx1 = st.x1 + dx1[i];
        int ny1 = st.y1 + dy1[i];
        int nx2 = st.x2 + dx2[i];
        int ny2 = st.y2 + dy2[i];
        State nst = st;
        nst.cost++;

        if (nx1 >= 0 && nx1 < w && ny1 >= 0 && ny1 < h && !t[ny1][nx1]) {
          nst.x1 = nx1;
          nst.y1 = ny1;
        }
        if (nx2 >= 0 && nx2 < w && ny2 >= 0 && ny2 < h && !t[ny2][nx2]) {
          nst.x2 = nx2;
          nst.y2 = ny2;
        }

        if (!closed[nst.x1][nst.y1][nst.x2][nst.y2]) {
          closed[nst.x1][nst.y1][nst.x2][nst.y2] = true;
          open.push(nst);
        }
      }
    }

    if (ans == -1)
      cout << "NA\\n";
    else
      cout << ans << endl;
  }

  return 0;
}


Error: MLE

Fixed submission:

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

int H, W;
bool F[52][52];         // 障害物
bool D[52][52][52][52]; // 探索済みかの判定用
int inc_tx[4] = {1, -1, 0, 0};
int inc_ty[4] = {0, 0, 1, -1};
int inc_kx[4] = {-1, 1, 0, 0};
int inc_ky[4] = {0, 0, -1, 1};

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;
  }
};

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

int main() {

  while (1) {

    Point p, q;
    int tx, ty, kx, ky;
    queue<Point> qa;
    cin >> W >> H;
    if (W == 0 && H == 0)
      break;
    cin >> tx >> ty >> kx >> ky;
    memset(F, 1, sizeof(F));
    for (int y = 1; y <= H; y++) {
      for (int x = 1; x <= W; x++) {
        cin >> F[y][x];
      }
    }
    memset(D, 1, sizeof(D));
    p.set(tx, ty, kx, ky);
    D[ty][tx][ky][kx] = 0;
    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;
      }
      for (int i = 0; i < 4; i++) {
        q.tx = p.tx + inc_tx[i];
        q.ty = p.ty + inc_ty[i];
        q.kx = p.kx + inc_kx[i];
        q.ky = p.ky + inc_ky[i];
        if (D[q.ty][q.tx][q.ky][q.kx]) {
          if (is_out_of_area(q.ty, q.tx) == 0 ||
              is_out_of_area(q.ky, q.kx) == 0) {
            if (is_out_of_area(q.ty, q.tx)) {
              q.ty = p.ty;
              q.tx = p.tx;
            }
            if (is_out_of_area(q.ky, q.kx)) {
              q.ky = p.ky;
              q.kx = p.kx;
            }
            q.d = p.d + 1;
            qa.push(q);
            D[q.ty][q.tx][q.ky][q.kx] = 0;
          }
        }
      }
    }
    while (!qa.empty()) {
      qa.pop();
    } // キューの残りカスを消去
  }
  return 0;
}