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

#include <bits/stdc++.h>

#define REP(i, s, n) for (int i = s; i < n; i++)
#define rep(i, n) REP(i, 0, n)

#define LEN 4

using namespace std;

// data
int8_t P[LEN][LEN];

void solve();
int main() {
  rep(i, LEN) {
    rep(j, LEN) {
      int p;
      cin >> p;
      P[i][j] = p;
    }
  }

  solve();
}

int manhattan(int8_t (*P)[LEN]) {
  int dst = 0;
  rep(i, LEN) {
    rep(j, LEN) {
      if (P[i][j] == 0)
        continue;

      int ti = (P[i][j] - 1) / LEN,
          tj = (P[i][j] - 1) % LEN; // target location
      dst += abs(ti - i) + abs(tj - j);
    }
  }

  return dst;
}

typedef pair<int, int> Pi;

struct State {
  State(int8_t (*P0)[LEN], int move0, Pi blankBef, Pi blankNow) {
    rep(i, LEN) rep(j, LEN) P[i][j] = P0[i][j];
    move = move0;
    dst = manhattan(P) + move;
    blank = blankNow;
    _blank = blankBef;
  }
  friend bool operator>(State s0, State s1) { return s0.dst > s1.dst; }
  int dst;
  int move;
  int8_t P[LEN][LEN];
  pair<int, int> blank, _blank;
};

const int di[4] = {-1, 1, 0, 0}, dj[4] = {0, 0, -1, 1};
void solve() {
  // find blank
  int bi, bj;
  rep(i, LEN) rep(j, LEN) if (P[i][j] == 0) bi = i, bj = j;

  State s0(P, 0, Pi(bi, bj), Pi(bi, bj));
  priority_queue<State, vector<State>, greater<State>> pq;
  pq.push(s0);

  while (!pq.empty()) {
    State s = pq.top();
    pq.pop();

    // check final
    if (manhattan(s.P) == 0) {
      cout << s.move << endl;
      break;
    }

    rep(i, 4) {
      int ii, jj;
      ii = s.blank.first + di[i];
      jj = s.blank.second + dj[i];

      if (ii >= 0 && ii < LEN && jj >= 0 && jj < LEN &&
          Pi(ii, jj) != s._blank) {
        swap(s.P[s.blank.first][s.blank.second], s.P[ii][jj]);

        pq.push(State(s.P, s.move + 1, s.blank, Pi(ii, jj)));

        swap(s.P[s.blank.first][s.blank.second], s.P[ii][jj]);
      }
    }
  }
}


Error: MLE

Fixed submission:

#include <bits/stdc++.h>

#define REP(i, s, n) for (int i = s; i < n; i++)
#define rep(i, n) REP(i, 0, n)

#define LEN 4

using namespace std;

// data
int P[LEN][LEN];

void solve();
int main() {
  rep(i, LEN) {
    rep(j, LEN) { cin >> P[i][j]; }
  }

  solve();
}

int manhattan(int (*P)[LEN]) {
  int dst = 0;
  rep(i, LEN) {
    rep(j, LEN) {
      if (P[i][j] == 0)
        continue;

      int ti = (P[i][j] - 1) / LEN,
          tj = (P[i][j] - 1) % LEN; // target location
      dst += abs(ti - i) + abs(tj - j);
    }
  }

  return dst;
}

typedef pair<int, int> Pi;

struct State {
  State(int (*P0)[LEN], int move0, Pi blankBef, Pi blankNow) {
    rep(i, LEN) rep(j, LEN) P[i][j] = P0[i][j];
    move = move0;
    dst = manhattan(P) + move;
    blank = blankNow;
    _blank = blankBef;
  }
  friend bool operator>(State s0, State s1) { return s0.dst > s1.dst; }
  int dst;
  int move;
  int P[LEN][LEN];
  pair<int, int> blank, _blank;
};

const int di[4] = {-1, 1, 0, 0}, dj[4] = {0, 0, -1, 1};
void solve() {
  // find blank
  int bi, bj;
  rep(i, LEN) rep(j, LEN) if (P[i][j] == 0) bi = i, bj = j;

  State s0(P, 0, Pi(bi, bj), Pi(bi, bj));
  priority_queue<State, vector<State>, greater<State>> pq;
  pq.push(s0);

  while (!pq.empty()) {
    State s = pq.top();
    pq.pop();

    // check final
    if (manhattan(s.P) == 0) {
      cout << s.move << endl;
      break;
    }

    rep(i, 4) {
      int ii, jj;
      ii = s.blank.first + di[i];
      jj = s.blank.second + dj[i];

      if (ii >= 0 && ii < LEN && jj >= 0 && jj < LEN &&
          Pi(ii, jj) != s._blank) {
        swap(s.P[s.blank.first][s.blank.second], s.P[ii][jj]);

        pq.push(State(s.P, s.move + 1, s.blank, Pi(ii, jj)));

        swap(s.P[s.blank.first][s.blank.second], s.P[ii][jj]);
      }
    }
  }
}