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

#include <algorithm>
#include <array>
#include <chrono>
#include <fstream>
#include <functional>
#include <iostream>
#include <map>
#include <memory.h>
#include <numeric>
#include <queue>
#include <stack>
#include <string>
#include <vector>

#pragma warning(disable : 4996)
#define REP(i, n) for (int i = 0; i < n; ++i)
typedef long long Int;

using namespace std;

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

const Int M_H(2);
const Int M_W(4);

short tile[M_H][M_W];
int H, W;
short dp[8][8][8][8][8][8][8];

struct point {
  Int x, y, step;
  short tile[M_H][M_W];
  int dx, dy;
  point(Int x_, Int y_, Int s, short tile_[M_H][M_W], int dx_, int dy_)
      : x(x_), y(y_), step(s), dx(dx_), dy(dy_) {
    memcpy(tile, tile_, sizeof(tile));
  }
};

queue<point> que;

bool check(short tile[M_H][M_W]) {

  for (int i = 0; i < 8; ++i) {
    if (tile[i / 4][i % 4] != i)
      return false;
  }
  return true;
}

int solve() {
  while (!que.empty()) {
    auto now = que.front();
    que.pop();

    if (!dp[now.tile[0][0]][now.tile[0][1]][now.tile[0][2]][now.tile[0][3]]
           [now.tile[1][0]][now.tile[1][1]][now.tile[1][2]])
      dp[now.tile[0][0]][now.tile[0][1]][now.tile[0][2]][now.tile[0][3]]
        [now.tile[1][0]][now.tile[1][1]][now.tile[1][2]] = now.step;
    else
      continue;

    int i(4);
    while (i--) {
      int x = now.x + dx[i];
      int y = now.y + dy[i];

      if (x >= M_W || x < 0 || y >= M_H || y < 0)
        continue;

      if (now.dx == -dx[i] && now.dy == -dy[i])
        continue;

      if (check(now.tile))
        return now.step;

      short temp[M_H][M_W];
      memcpy(temp, now.tile, sizeof(temp));
      short temp_2 = temp[y][x];
      temp[y][x] = 0;
      temp[y - dy[i]][x - dx[i]] = temp_2;
      que.emplace(x, y, now.step + 1, temp, dx[i], dy[i]);
    }
  }
  return -1;
}

int main() {
  cin.tie(0);
  ios::sync_with_stdio(false);
  // fstream fs("input.txt");
  ////////////ここから開始///////////
  // fs >> W >> H;
  int(n);
  while (cin >> n) {
    memset(dp, 0, sizeof(dp));
    tile[0][0] = n;
    for (int i = 1; i < 8; ++i) {
      cin >> tile[i / 4][i % 4];
    }

    que = {};

    REP(i, 2) REP(j, 4) {
      if (tile[i][j] == 0) {
        que.emplace(j, i, 0, tile, 0, 0);
      }
    }
    cout << solve() << endl;
  }

  return 0;
}

Error: MLE

Fixed submission:

#include <algorithm>
#include <array>
#include <chrono>
#include <fstream>
#include <functional>
#include <iostream>
#include <memory.h>
#include <numeric>
#include <queue>
#include <stack>
#include <string>
#include <vector>

#pragma warning(disable : 4996)
#define REP(i, n) for (int i = 0; i < n; ++i)
typedef long long Int;

using namespace std;

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

const Int M_H(2);
const Int M_W(4);

short tile[M_H][M_W];
int H, W;

struct point {
  Int x, y, step;
  short tile[M_H][M_W];
  int dx, dy;
  point(Int x_, Int y_, Int s, short tile_[M_H][M_W], int dx_, int dy_)
      : x(x_), y(y_), step(s), dx(dx_), dy(dy_) {
    memcpy(tile, tile_, sizeof(tile));
  }
};

queue<point> que;

bool check(short tile[M_H][M_W]) {

  for (int i = 0; i < 8; ++i) {
    if (tile[i / 4][i % 4] != i)
      return false;
  }
  return true;
}

int solve() {
  while (!que.empty()) {
    auto now = que.front();
    que.pop();

    int i(4);
    while (i--) {
      int x = now.x + dx[i];
      int y = now.y + dy[i];

      if (x >= M_W || x < 0 || y >= M_H || y < 0)
        continue;

      if (now.dx == -dx[i] && now.dy == -dy[i])
        continue;

      if (check(now.tile))
        return now.step;

      short temp[M_H][M_W];
      memcpy(temp, now.tile, sizeof(temp));
      short temp_2 = temp[y][x];
      temp[y][x] = 0;
      temp[y - dy[i]][x - dx[i]] = temp_2;
      que.emplace(x, y, now.step + 1, temp, dx[i], dy[i]);
    }
  }
  return -1;
}

int main() {
  cin.tie(0);
  ios::sync_with_stdio(false);
  // fstream fs("input.txt");
  ////////////ここから開始///////////
  // fs >> W >> H;
  int(n);
  while (cin >> n) {
    tile[0][0] = n;
    for (int i = 1; i < 8; ++i) {
      cin >> tile[i / 4][i % 4];
    }

    que = {};

    REP(i, 2) REP(j, 4) {
      if (tile[i][j] == 0) {
        que.emplace(j, i, 0, tile, 0, 0);
      }
    }
    cout << solve() << endl;
  }

  return 0;
}