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

#include <cstring>
#include <iostream>
#include <queue>

using namespace std;

#define NUM 3

typedef struct STATUS {
  int num;              //????????????????????????????????°
  int board[NUM * NUM]; //?????¢?????¶???
  int x, y;             //?????¢???0???????????????????????§?¨?
} STATUS;

bool checked[9 * 8 * 7 * 6 * 5 * 4 * 3 * 2 * 1];

/* ?????¢?????¶????????????????????? */
int change_number(int *board) {
  int work[NUM * NUM];
  static int fact_table[NUM * NUM] = {
      40320, 5040, 720, 120, 24, 6, 2, 1, 0,
  };
  int j, k, value = 0;
  memcpy(work, board, sizeof(int) * NUM * NUM);
  for (j = 0; j < NUM * NUM - 1; j++) {
    value += fact_table[j] * work[j];
    for (k = j + 1; k < NUM * NUM; k++) {
      if (work[j] < work[k])
        work[k]--;
    }
  }
  return value;
}

int search(STATUS in) {

  int x = 0, y = 0;
  int chk_num, goal_num;

  int dx[4] = {1, 0, -1, 0};
  int dy[4] = {0, 1, 0, -1};

  int goal[9] = {1, 2, 3, 4, 5, 6, 7, 8, 0};
  STATUS out;
  goal_num = change_number(goal);

  //?????¢?????¶????????????????????????????????\\???
  queue<STATUS> qu;
  qu.push(in);

  //?????\\???????????????????????§?¶???????
  while (!qu.empty()) {

    in = qu.front();
    qu.pop();
    chk_num = change_number(in.board);
    if (goal_num == chk_num) {
      return in.num;
    } else {
      checked[chk_num] = true;
    }
    for (int i = 0; i < 4; i++) {
      //?????¢???0???????????????????????§?¨????x,y???????????????
      x = in.x;
      y = in.y;
      if (x + dx[i] >= 0 && x + dx[i] < NUM && y + dy[i] >= 0 &&
          y + dy[i] < NUM) {
        memcpy(&out, &in, sizeof(STATUS));
        swap(out.board[NUM * y + x], out.board[NUM * (y + dy[i]) + x + dx[i]]);

        chk_num = change_number(out.board);
        if (checked[chk_num] == true) {
          continue;
        } else {
          out.num++;
          out.x = x + dx[i];
          out.y = y + dy[i];
          qu.push(out);
        }
      }
    }
  }

  //?????¢???goal?????°??????????????£?????´??????-1?????????
  return -1;
}

int main() {

  int val, ans;

  STATUS init;
  init.num = 0;

  for (int i = 0; i < NUM; i++) {
    for (int j = 0; j < NUM; j++) {
      cin >> val;
      init.board[i * NUM + j] = val;
      if (val == 0) {
        init.x = j;
        init.y = i;
      }
    }
  }

  ans = search(init);

  cout << ans << endl;

  return 0;
}

Error: MLE

Fixed submission:

#include <cstring>
#include <iostream>

using namespace std;

#define NUM 3
#define PRUNING 50

#define MAX 500000000
char passed[MAX];

typedef struct STATUS {
  int num;
  int board[NUM][NUM];
} STATUS;

typedef pair<int, int> cell;

bool checkfinish(STATUS in) {

  int val = 1;

  for (int i = 0; i < NUM; i++) {
    for (int j = 0; j < NUM; j++) {
      if (i == NUM - 1 && j == NUM - 1)
        return true;
      if (in.board[i][j] != val++)
        return false;
    }
  }
  return true;
}

int rtnindex(STATUS in) {

  int ret = 0;
  int val = 1;

  for (int i = 0; i < NUM; i++) {
    for (int j = 0; j < NUM; j++) {
      ret += val * in.board[i][j];
      val *= 9;
    }
  }
  return ret;
}

int backtrack(STATUS in, cell last_zero) {

  int x = 0, y = 0, ret = PRUNING;
  cell zero;
  STATUS out;

  int dx[4] = {1, 0, -1, 0};
  int dy[4] = {0, 1, 0, -1};

  if (in.num > ret) {
    return ret;
  }

  if (checkfinish(in)) {
    return in.num;
  }

  for (int i = 0; i < NUM; i++) {
    for (int j = 0; j < NUM; j++) {
      if (in.board[i][j] == 0) {
        x = zero.first = j;
        y = zero.second = i;
      }
    }
  }

  for (int i = 0; i < 4; i++) {
    if (x + dx[i] >= 0 && x + dx[i] < NUM && y + dy[i] >= 0 &&
        y + dy[i] < NUM) {
      if (last_zero.first == x + dx[i] && last_zero.second == y + dy[i]) {
        continue;
      }
      memcpy(&out, &in, sizeof(STATUS));
      swap(out.board[y][x], out.board[y + dy[i]][x + dx[i]]);
      int rtn = rtnindex(out);
      if (passed[rtn] == 1) {
        continue;
      }
      out.num++;
      ret = min(ret, backtrack(out, zero));
      passed[rtn] = 1;
    }
  }
  return ret;
}

int main() {

  int val, ans;

  STATUS init;
  init.num = 0;

  for (int i = 0; i < NUM; i++) {
    for (int j = 0; j < NUM; j++) {
      cin >> val;
      init.board[i][j] = val;
    }
  }

  for (int i = 0; i < MAX; i++)
    passed[i] = 0;

  passed[rtnindex(init)] = 1;

  //?????????????????????????????????zero????????¨?????????????????????????????\\????????????
  ans = backtrack(init, cell(-1, -1));

  cout << ans << endl;

  return 0;
}