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

#include <bits/stdc++.h>
using namespace std;
#define N 4
#define NN 16
#define LIMIT 45

struct P {
  int f[NN];
  int t;
  int st;
  bool operator<(const P &p) const {
    for (int i = 0; i < NN; i++) {
      if (f[i] == p.f[i])
        continue;
      return f[i] > p.f[i];
    }
    return false;
  }
};

struct Cost {
  P p;
  int cost;
  bool operator<(const Cost &c) const { return cost + p.t > c.cost + c.p.t; }
};

int man(int f[]) {
  int ans = 0;
  for (int i = 0; i < NN; i++) {
    if (f[i] == 0)
      continue;
    ans += abs((f[i] - 1) / N - i / N);
    ans += abs((f[i] - 1) % N - i % N);
  }
  return ans;
}

int main() {
  P in;
  map<P, bool> V;
  priority_queue<Cost> Q;
  for (int i = 0; i < NN; i++) {
    cin >> in.f[i];
    if (in.f[i] == 0)
      in.st = i;
  }
  in.t = 0;
  Cost t;
  t.p = in;
  t.cost = man(t.p.f);
  Q.push(t);
  while (!Q.empty()) {
    P top = Q.top().p;
    Q.pop();

    if (man(top.f) + top.t <= LIMIT) {
      V[top] = true;
      int flag = 0;
      for (int i = 0; i < NN; i++) {
        if ((i + 1) % NN == top.f[i])
          flag++;
      }
      if (flag == NN) {
        cout << top.t << endl;
        break;
      }
      int st = top.st;
      top.t++;
      P tmp;
      if (st - N >= 0) {
        tmp = top;
        swap(tmp.f[st], tmp.f[st - N]);
        tmp.st -= N;
        if (!V[tmp] && man(tmp.f) + tmp.t <= LIMIT) {
          V[tmp] = true;
          Cost t;
          t.p = tmp;
          t.cost = man(t.p.f);
          Q.push(t);
        }
      }
      if (st + N < NN) {
        tmp = top;
        swap(tmp.f[st], tmp.f[st + N]);
        tmp.st += N;
        if (!V[tmp] && man(tmp.f) + tmp.t <= LIMIT) {
          V[tmp] = true;
          Cost t;
          t.p = tmp;
          t.cost = man(t.p.f);
          Q.push(t);
        }
      }
      if (st % N != N - 1) {
        tmp = top;
        swap(tmp.f[st], tmp.f[st + 1]);
        tmp.st++;
        if (!V[tmp] && man(tmp.f) + tmp.t <= LIMIT) {
          V[tmp] = true;
          Cost t;
          t.p = tmp;
          t.cost = man(t.p.f);
          Q.push(t);
        }
      }
      if (st % N != 0) {
        tmp = top;
        swap(tmp.f[st], tmp.f[st - 1]);
        tmp.st--;
        if (!V[tmp] && man(tmp.f) + tmp.t <= LIMIT) {
          V[tmp] = true;
          Cost t;
          t.p = tmp;
          t.cost = man(t.p.f);
          Q.push(t);
        }
      }
    }
  }
  return 0;
}

Error: MLE

Fixed submission:

#include <bits/stdc++.h>
using namespace std;
#define N 4
#define NN 16
#define LIMIT 45

struct P {
  int f[NN];
  int t;
  int st;
  bool operator<(const P &p) const {
    for (int i = 0; i < NN; i++) {
      if (f[i] == p.f[i])
        continue;
      return f[i] > p.f[i];
    }
    return false;
  }
};

struct Cost {
  P p;
  int cost;
  bool operator<(const Cost &c) const { return cost + p.t > c.cost + c.p.t; }
};

int man(int f[]) {
  int ans = 0;
  for (int i = 0; i < NN; i++) {
    if (f[i] == 0)
      continue;
    ans += abs((f[i] - 1) / N - i / N);
    ans += abs((f[i] - 1) % N - i % N);
  }
  return ans;
}

int main() {
  P in;
  map<P, bool> V;
  priority_queue<Cost> Q;
  for (int i = 0; i < NN; i++) {
    cin >> in.f[i];
    if (in.f[i] == 0)
      in.st = i;
  }
  in.t = 0;
  Cost t;
  t.p = in;
  t.cost = man(t.p.f);
  Q.push(t);
  while (!Q.empty()) {
    P top = Q.top().p;
    Q.pop();

    if (man(top.f) + top.t <= LIMIT) {
      V[top] = true;
      int flag = 0;
      for (int i = 0; i < NN; i++) {
        if ((i + 1) % NN == top.f[i])
          flag++;
      }
      if (flag == NN) {
        cout << top.t << endl;
        break;
      }
      int st = top.st;
      top.t++;
      P tmp;
      if (st - N >= 0) {
        tmp = top;
        swap(tmp.f[st], tmp.f[st - N]);
        tmp.st -= N;
        if (!V[tmp]) {
          V[tmp] = true;
          Cost t;
          t.p = tmp;
          t.cost = man(t.p.f);
          Q.push(t);
        }
      }
      if (st + N < NN) {
        tmp = top;
        swap(tmp.f[st], tmp.f[st + N]);
        tmp.st += N;
        if (!V[tmp]) {
          V[tmp] = true;
          Cost t;
          t.p = tmp;
          t.cost = man(t.p.f);
          Q.push(t);
        }
      }
      if (st % N != N - 1) {
        tmp = top;
        swap(tmp.f[st], tmp.f[st + 1]);
        tmp.st++;
        if (!V[tmp]) {
          V[tmp] = true;
          Cost t;
          t.p = tmp;
          t.cost = man(t.p.f);
          Q.push(t);
        }
      }
      if (st % N != 0) {
        tmp = top;
        swap(tmp.f[st], tmp.f[st - 1]);
        tmp.st--;
        if (!V[tmp]) {
          V[tmp] = true;
          Cost t;
          t.p = tmp;
          t.cost = man(t.p.f);
          Q.push(t);
        }
      }
    }
  }
  return 0;
}