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

#include <bits/stdc++.h>
#include <unordered_set>
using namespace std;

typedef long long ll;
typedef unsigned long long ull;
typedef pair<ll, ll> P;

#define fi first
#define se second
#define repl(i, a, b) for (ll i = (ll)(a); i < (ll)(b); i++)
#define rep(i, n) repl(i, 0, n)
#define each(itr, v) for (auto itr : v)
#define pb push_back
#define all(x) (x).begin(), (x).end()
#define dbg(x) cout << #x "=" << x << endl
#define mmax(x, y) (x > y ? x : y)
#define mmin(x, y) (x < y ? x : y)
#define maxch(x, y) x = mmax(x, y)
#define minch(x, y) x = mmin(x, y)
#define uni(x) x.erase(unique(all(x)), x.end())
#define exist(x, y) (find(all(x), y) != x.end())
#define bcnt __builtin_popcount

#define INF INT_MAX / 3

const int N = 4;

struct state {
  vector<char> board;
  char dist;
  char bi, bj;
  char mh_dist;
  char pre;
};

map<vector<char>, bool> vis;

bool operator<(const state &a, const state &b) {
  return a.dist + a.mh_dist > b.dist + b.mh_dist;
}

int di[] = {0, 1, 0, -1};
int dj[] = {1, 0, -1, 0};

/*
int ans[N][N]={
  {0,1,2},
  {3,4,5},
  {6,7,-1},
};*/

int ans[N][N] = {
    {0, 1, 2, 3},
    {4, 5, 6, 7},
    {8, 9, 10, 11},
    {12, 13, 14, -1},
};

P ans_ps[N * N];

int main() {

  clock_t start = clock();

  rep(i, N) rep(j, N) {
    if (ans[i][j] == -1)
      continue;
    ans_ps[ans[i][j]].fi = i;
    ans_ps[ans[i][j]].se = j;
  }

  state inistate;
  inistate.board = vector<char>(N * N);
  inistate.dist = 0;
  inistate.mh_dist = 0;
  inistate.pre = -1;
  rep(i, N) rep(j, N) {
    int input;
    cin >> input;
    input--;
    inistate.board[i * N + j] = input;
    if (input == -1) {
      inistate.bi = i;
      inistate.bj = j;
    } else {
      int ai = ans_ps[input].fi;
      int aj = ans_ps[input].se;
      inistate.mh_dist += abs(ai - i) + abs(aj - j);
    }
  }

  priority_queue<state> que;
  que.push(inistate);
  while (que.size()) {
    state crtstate = que.top();
    que.pop();
    if (crtstate.mh_dist == 0) {
      cout << (int)crtstate.dist << endl;
      break;
    }
    vis[crtstate.board] = true;
    rep(dir, 4) {
      if (dir == crtstate.pre)
        continue;
      int bi = crtstate.bi;
      int bj = crtstate.bj;
      int ni = bi + di[dir];
      int nj = bj + dj[dir];
      if (ni < 0 || ni >= N || nj < 0 || nj >= N)
        continue;
      state nxtstate;
      nxtstate.board = crtstate.board;
      nxtstate.dist = crtstate.dist;
      nxtstate.mh_dist = crtstate.mh_dist;

      char num = crtstate.board[ni * N + nj];
      int ai = ans_ps[num].fi;
      int aj = ans_ps[num].se;
      nxtstate.mh_dist -= abs(ai - ni) + abs(aj - nj);
      nxtstate.mh_dist += abs(ai - bi) + abs(aj - bj);

      swap(nxtstate.board[bi * N + bj], nxtstate.board[ni * N + nj]);
      nxtstate.dist++;
      nxtstate.bi = ni;
      nxtstate.bj = nj;
      nxtstate.pre = (dir + 2) % 4;
      if (!vis[nxtstate.board]) {
        vis[nxtstate.board] = true;
        que.push(nxtstate);
      }
    }
  }

  clock_t end = clock();
  // cerr<<"duration = "<<(double)(end-start)/CLOCKS_PER_SEC<<" sec."<<endl;

  return 0;
}

Error: MLE

Fixed submission:

#include <bits/stdc++.h>
#include <unordered_set>
using namespace std;

typedef long long ll;
typedef unsigned long long ull;
typedef pair<ll, ll> P;

#define fi first
#define se second
#define repl(i, a, b) for (ll i = (ll)(a); i < (ll)(b); i++)
#define rep(i, n) repl(i, 0, n)
#define each(itr, v) for (auto itr : v)
#define pb push_back
#define all(x) (x).begin(), (x).end()
#define dbg(x) cout << #x "=" << x << endl
#define mmax(x, y) (x > y ? x : y)
#define mmin(x, y) (x < y ? x : y)
#define maxch(x, y) x = mmax(x, y)
#define minch(x, y) x = mmin(x, y)
#define uni(x) x.erase(unique(all(x)), x.end())
#define exist(x, y) (find(all(x), y) != x.end())
#define bcnt __builtin_popcount

#define INF INT_MAX / 3

const int N = 4;

struct state {
  vector<vector<int>> board;
  int dist;
  int bi, bj;
  int mh_dist;
  int pre;
};

map<vector<vector<int>>, int> d;

bool operator<(const state &a, const state &b) {
  return a.dist + a.mh_dist > b.dist + b.mh_dist;
}

int di[] = {0, 1, 0, -1};
int dj[] = {1, 0, -1, 0};

/*
int ans[N][N]={
  {0,1,2},
  {3,4,5},
  {6,7,-1},
};*/

int ans[N][N] = {
    {0, 1, 2, 3},
    {4, 5, 6, 7},
    {8, 9, 10, 11},
    {12, 13, 14, -1},
};

P ans_ps[N * N];

int main() {

  clock_t start = clock();

  rep(i, N) rep(j, N) {
    if (ans[i][j] == -1)
      continue;
    ans_ps[ans[i][j]].fi = i;
    ans_ps[ans[i][j]].se = j;
  }

  state inistate;
  inistate.board = vector<vector<int>>(N, vector<int>(N));
  inistate.dist = 0;
  inistate.mh_dist = 0;
  inistate.pre = -1;
  rep(i, N) rep(j, N) {
    int input;
    cin >> input;
    input--;
    inistate.board[i][j] = input;
    if (input == -1) {
      inistate.bi = i;
      inistate.bj = j;
    } else {
      int ai = ans_ps[input].fi;
      int aj = ans_ps[input].se;
      inistate.mh_dist += abs(ai - i) + abs(aj - j);
    }
  }

  priority_queue<state> que;
  que.push(inistate);
  d[inistate.board] = inistate.dist + inistate.mh_dist;
  while (que.size()) {
    state crtstate = que.top();
    que.pop();
    if (crtstate.dist + crtstate.mh_dist > d[crtstate.board])
      continue;
    if (crtstate.mh_dist == 0) {
      cout << crtstate.dist << endl;
      break;
    }
    rep(dir, 4) {
      if (dir == crtstate.pre)
        continue;
      int bi = crtstate.bi;
      int bj = crtstate.bj;
      int ni = bi + di[dir];
      int nj = bj + dj[dir];
      if (ni < 0 || ni >= N || nj < 0 || nj >= N)
        continue;
      state nxtstate;
      nxtstate.board = crtstate.board;
      nxtstate.dist = crtstate.dist;
      nxtstate.mh_dist = crtstate.mh_dist;

      int num = crtstate.board[ni][nj];
      int ai = ans_ps[num].fi;
      int aj = ans_ps[num].se;
      nxtstate.mh_dist -= abs(ai - ni) + abs(aj - nj);
      nxtstate.mh_dist += abs(ai - bi) + abs(aj - bj);

      swap(nxtstate.board[bi][bj], nxtstate.board[ni][nj]);
      nxtstate.dist++;
      nxtstate.bi = ni;
      nxtstate.bj = nj;
      nxtstate.pre = (dir + 2) % 4;
      if (d.find(nxtstate.board) == d.end() ||
          d[nxtstate.board] > nxtstate.dist + nxtstate.mh_dist) {
        d[nxtstate.board] = nxtstate.dist + nxtstate.mh_dist;
        que.push(nxtstate);
      }
    }
  }

  clock_t end = clock();
  // cerr<<"duration = "<<(double)(end-start)/CLOCKS_PER_SEC<<" sec."<<endl;

  return 0;
}