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

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

class state {
public:
  int *num;
  int time;
  int space;

  state() { num = new int[9]; }

  state(int time) {
    num = new int[9];
    this->time = time;
  }

  state(const state &st) {
    num = new int[9];
    for (int i = 0; i < 9; i++)
      num[i] = st.num[i];
    time = st.time;
    space = st.space;
  }

  ~state() { delete[] num; }

  bool operator<(const state &a) const {
    for (int i = 0; i < 9; i++) {
      if (num[i] == a.num[i])
        continue;
      return num[i] < a.num[i];
    }
    return false;
  }

  bool check_ans() {
    bool flag = true;
    for (int i = 0; i < 9; i++) {
      if (num[i] != i + 1)
        flag = false;
    }
    return flag;
  }

  // コード1~4を指定して、パズルを移動させる
  state operate(int i) {
    int dx[4] = {-1, 0, 1, 0}, dy[4] = {0, -1, 0, 1}; // 移動方向
    int nx = space % 3 + dx[i], ny = space / 3 + dy[i];
    state ns = *this;
    ns.swap(ny * 3 + nx, space);

    ns.time = time + 1;
    ns.space = ny * 3 + nx;

    return ns;
  }

  bool direction_check(int i) {
    int dx[4] = {-1, 0, 1, 0}, dy[4] = {0, -1, 0, 1}; // 移動方向
    int nx = space % 3 + dx[i], ny = space / 3 + dy[i];
    if (nx < 0 || 2 < nx || ny < 0 || 2 < ny)
      return false;
    return true;
  }

private:
  // numのn1番目の要素とn2番目の要素を入れ替える
  void swap(int n1, int n2) {
    int temp = num[n1];
    num[n1] = num[n2];
    num[n2] = temp;
  }
};
int main() {
  state start(0); // 初期状態の生成
  for (int i = 0; i < 9; i++) {
    cin >> start.num[i];
    if (start.num[i] == 0) {
      start.num[i] = 9;
      start.space = i;
    }
  }

  // 重複を避けるためのmap
  map<state, bool> mp;
  mp[start] = true;

  // bfs用のqueue生成
  queue<state> q;
  q.push(start);

  // queueが空になるまで
  while (!q.empty()) {
    state now = q.front();
    q.pop();

    // もし取り出した状態が所望の状態なら、かかった回数を表示して終了
    if (now.check_ans()) {
      cout << now.time << endl;
      break;
    }

    for (int i = 0; i < 4; i++) {
      if (!now.direction_check(i))
        continue;
      state ns = now.operate(i);
      if (!mp[ns]) {
        mp[ns] = true;
        q.push(ns);
      }
    }
  }

  return 0;
}


Error: MLE

Fixed submission:

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

class state {
public:
  int *num;
  int time;

  state() { num = new int[9]; }

  state(int time) {
    num = new int[9];
    this->time = time;
  }

  state(const state &st) {
    num = new int[9];
    for (int i = 0; i < 9; i++)
      num[i] = st.num[i];
    time = st.time;
  }

  ~state() { delete[] num; }

  bool check() {
    bool flag = true;
    for (int i = 0; i < 8; i++) {
      if (num[i] != i + 1)
        flag = false;
    }
    return flag && (num[8] == 0);
  }

  // コード1~12を指定して、パズルを移動させる
  state operate(int i) {
    state ns = *this;
    assert(1 <= i && i <= 12);
    switch (i) {
    case 1:
      ns.swap(0, 1);
      break;
    case 2:
      ns.swap(1, 2);
      break;
    case 3:
      ns.swap(3, 4);
      break;
    case 4:
      ns.swap(4, 5);
      break;
    case 5:
      ns.swap(6, 7);
      break;
    case 6:
      ns.swap(7, 8);
      break;
    case 7:
      ns.swap(0, 4);
      break;
    case 8:
      ns.swap(1, 5);
      break;
    case 9:
      ns.swap(2, 6);
      break;
    case 10:
      ns.swap(3, 6);
      break;
    case 11:
      ns.swap(4, 7);
      break;
    case 12:
      ns.swap(5, 8);
      break;
    }
    ns.time = time + 1;
    return ns;
  }

private:
  // numのn1番目の要素とn2番目の要素を入れ替える
  void swap(int n1, int n2) {
    int temp = num[n1];
    num[n1] = num[n2];
    num[n2] = temp;
  }
};
int main() {
  state start(0); // 初期状態の生成
  for (int i = 0; i < 9; i++)
    cin >> start.num[i];

  // bfs用のqueue生成
  queue<state> q;
  q.push(start);

  // queueが空になるまで
  while (!q.empty()) {
    state now = q.front();
    q.pop();

    // もし取り出した状態が所望の状態ならかかった回数を表示して終了
    if (now.check()) {
      cout << now.time << endl;
      break;
    }

    for (int i = 1; i <= 12; i++) {
      q.push(now.operate(i));
    }
  }

  return 0;
}