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) {
        cout << "NA" << endl;
        break;
      }

      if (p.tx == p.kx && p.ty == p.ky) {
        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;

const int INF = 100000000;

class Twin {
public:
  int tx;
  int ty;
  int kx;
  int ky;
  int n;
};

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

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

    int tx, ty;
    int kx, ky;
    cin >> tx >> ty;
    cin >> kx >> ky;

    int F[52][52];
    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++) {
        cin >> F[y][x];
      }
    }

    int D[52][52];
    for (int y = 1; y <= H; y++) {
      for (int x = 1; x <= W; x++) {
        D[y][x] = INF;
      }
    }

    queue<Twin> que;

    Twin p;
    p.tx = tx;
    p.ty = ty;
    p.kx = kx;
    p.ky = ky;
    p.n = 0;
    que.push(p);

    D[p.ty][p.tx] = 0;
    D[p.ky][p.kx] = 0;

    while (!que.empty()) {
      p = que.front();
      que.pop();

      // cout << D[p.ty][p.tx] << ' ' << p.tx << ',' << p.ty << endl;
      // cout << " ," << p.kx << ',' << p.ky << endl;

      if (p.tx == p.kx && p.ty == p.ky) {
        /*for(int y=1; y<=H; y++){
          for(int x=1; x<=W; x++){
            cout << D[y][x] << ' ';
          }
          cout << endl;
          }*/
        cout << p.n << endl;
        break;
      }
      if (p.n >= 100) {
        // cout << p.n << endl;
        cout << "NA" << endl;
        break;
      }

      if (F[p.ty - 1][p.tx] == 0 || F[p.ky + 1][p.kx] == 0) { // T上
        if (D[p.ty - 1][p.tx] >=
            D[p.ty][p.tx] /* && D[p.ky+1][p.kx]>=D[p.ky][p.kx]*/) {
          // cout << "T-top" << endl;
          Twin q;
          if (F[p.ty - 1][p.tx] == 0) {
            q.tx = p.tx;
            q.ty = p.ty - 1;
            if (D[q.ty][q.tx] > D[p.ty][p.tx]) {
              D[q.ty][q.tx] = D[p.ty][p.tx] + 1;
            }
          } else {
            q.tx = p.tx;
            q.ty = p.ty;
            if (D[q.ty][q.tx] > D[p.ty][p.tx]) {
              D[q.ty][q.tx] = D[p.ty][p.tx] + 1;
            } else if (q.tx == p.tx && q.ty == p.ty) {
              D[q.ty][q.tx] = D[p.ty][p.tx] + 1;
            }
          }
          if (F[p.ky + 1][p.kx] == 0) {
            q.kx = p.kx;
            q.ky = p.ky + 1;
            // D[q.ky][q.kx] = 0;
          } else {
            q.kx = p.kx;
            q.ky = p.ky;
            // D[q.ky][q.kx] = 0;
          }
          q.n = p.n + 1;
          // cout << q.ty << ' ' <<  q.ky << endl;
          que.push(q);
        }
      }
      if (F[p.ty + 1][p.tx] == 0 || F[p.ky - 1][p.kx] == 0) { // T下
        if (D[p.ty + 1][p.tx] >=
            D[p.ty][p.tx] /* && D[p.ky-1][p.kx]>=D[p.ky][p.kx]*/) {
          // cout << "T-bottom" << endl;
          Twin q;
          if (F[p.ty + 1][p.tx] == 0) {
            q.tx = p.tx;
            q.ty = p.ty + 1;
            if (D[q.ty][q.tx] > D[p.ty][p.tx]) {
              D[q.ty][q.tx] = D[p.ty][p.tx] + 1;
            }
          } else {
            q.tx = p.tx;
            q.ty = p.ty;
            if (D[q.ty][q.tx] > D[p.ty][p.tx]) {
              D[q.ty][q.tx] = D[p.ty][p.tx] + 1;
            } else if (q.tx == p.tx && q.ty == p.ty) {
              D[q.ty][q.tx] = D[p.ty][p.tx] + 1;
            }
          }
          if (F[p.ky - 1][p.kx] == 0) {
            q.kx = p.kx;
            q.ky = p.ky - 1;
            // D[q.ky][q.kx] = 0;
          } else {
            q.kx = p.kx;
            q.ky = p.ky;
            // D[q.ky][q.kx] = 0;
          }
          q.n = p.n + 1;
          // cout << q.ty << ' ' <<  q.ky << endl;
          que.push(q);
        }
      }
      if (F[p.ty][p.tx - 1] == 0 || F[p.ky][p.kx + 1] == 0) { // T左
        if (D[p.ty][p.tx - 1] >=
            D[p.ty][p.tx] /* && D[p.ky][p.kx+1]>=D[p.ky][p.kx]*/) {
          // cout << "T-left" << endl;
          Twin q;
          if (F[p.ty][p.tx - 1] == 0) {
            q.tx = p.tx - 1;
            q.ty = p.ty;
            if (D[q.ty][q.tx] > D[p.ty][p.tx]) {
              D[q.ty][q.tx] = D[p.ty][p.tx] + 1;
            }
          } else {
            q.tx = p.tx;
            q.ty = p.ty;
            if (D[q.ty][q.tx] > D[p.ty][p.tx]) {
              D[q.ty][q.tx] = D[p.ty][p.tx] + 1;
            } else if (q.tx == p.tx && q.ty == p.ty) {
              D[q.ty][q.tx] = D[p.ty][p.tx] + 1;
            }
          }
          if (F[p.ky][p.kx + 1] == 0) {
            q.kx = p.kx + 1;
            q.ky = p.ky;
            // D[q.ky][q.kx] = 0;
          } else {
            q.kx = p.kx;
            q.ky = p.ky;
            // D[q.ky][q.kx] = 0;
          }
          q.n = p.n + 1;
          // cout << q.tx << ' ' <<  q.kx << endl;
          que.push(q);
        }
      }
      if (F[p.ty][p.tx + 1] == 0 || F[p.ky][p.kx - 1] == 0) { // T右
        if (D[p.ty][p.tx + 1] >=
            D[p.ty][p.tx] /* && D[p.ky][p.kx-1]>=D[p.ky][p.kx]*/) {
          // cout << "T-right" << endl;
          Twin q;
          if (F[p.ty][p.tx + 1] == 0) {
            q.tx = p.tx + 1;
            q.ty = p.ty;
            if (D[q.ty][q.tx] > D[p.ty][p.tx]) {
              D[q.ty][q.tx] = D[p.ty][p.tx] + 1;
            }
          } else {
            q.tx = p.tx;
            q.ty = p.ty;
            if (D[q.ty][q.tx] > D[p.ty][p.tx]) {
              D[q.ty][q.tx] = D[p.ty][p.tx] + 1;
            } else if (q.tx == p.tx && q.ty == p.ty) {
              D[q.ty][q.tx] = D[p.ty][p.tx] + 1;
            }
          }
          if (F[p.ky][p.kx - 1] == 0) {
            q.kx = p.kx - 1;
            q.ky = p.ky;
            // D[q.ky][q.kx] = 0;
          } else {
            q.kx = p.kx;
            q.ky = p.ky;
            // D[q.ky][q.kx] = 0;
          }
          q.n = p.n + 1;
          // cout << q.tx << ' ' <<  q.kx << endl;
          que.push(q);
        }
      }
    }

    if (p.tx == p.kx && p.ty == p.ky) {
      continue;
    } else if (p.n < 100) {
      cout << "NA" << endl;
    }
  }

  return 0;
}