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

#include "bits/stdc++.h"
#include <unordered_map>
#pragma warning(disable : 4996)
using namespace std;

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

int cost[2];

struct aa {
  vector<int> field;
  int aaa;
  int cost;
};
aa mo(aa a, const int way) {
  const int ncost(a.cost + cost[way % 2]);
  int aaaa;
  if (way == 0) {
    aaaa = ((a.aaa) + 8) % 9;
  } else if (way == 1) {
    aaaa = ((a.aaa) + 3) % 9;
  } else if (way == 2) {
    aaaa = ((a.aaa) + 1) % 9;
  } else {
    aaaa = ((a.aaa) + 6) % 9;
  }

  swap(a.field[a.aaa], a.field[aaaa]);
  a.aaa = aaaa;
  a.cost = ncost;
  return a;
}
class Compare {
public:
  // keiroが昇順に並ぶ
  bool operator()(const aa &l, const aa &r) { return l.cost > r.cost; }
};
class HashVI { // ハッシュ関数オブジェクト
public:
  size_t operator()(const vector<int> &x) const {
    const int C = 997; // 素数
    size_t t = 0;
    for (int i = 0; i != x.size(); ++i) {
      t = t * C + x[i];
    }
    return t;
  }
  size_t operator()(const vector<vector<int>> &x) const {
    const int C = 997; // 素数
    size_t t = 0;
    for (int i = 0; i != x.size(); ++i) {
      for (int j = 0; j < x[i].size(); ++j) {
        t = t * C + x[i][j];
      }
    }
    return t;
  }
  size_t operator()(const vector<vector<short>> &x) const {
    const int C = 9; // 素数
    size_t t = 0;
    for (int i = 0; i != x.size(); ++i) {
      for (int j = 0; j < x[i].size(); ++j) {
        t = t * C + x[i][j];
      }
    }
    return t;
  }
};

unordered_map<vector<int>, int, HashVI> mp;

int main() {
  while (1) {
    mp.clear();
    cin >> cost[0] >> cost[1];
    if (!cost[0] && !cost[1])
      break;
    short vx, vy;
    vector<int> field(9);
    for (int y = 0; y < 9; ++y) {
      int a;
      cin >> a;
      if (!a) {
        vx = y;
      }
      field[y] = a;
    }
    vector<int> ans(9);
    for (int y = 0; y < 9; ++y) {
      int a;
      cin >> a;

      ans[y] = a;
    }
    priority_queue<aa, vector<aa>, Compare> que;
    que.push(aa{field, vx, 0});

    int anscost = 0;

    anscost = 999999;
    while (!que.empty()) {
      aa atop(que.top());
      if (atop.field == ans) {
        anscost = atop.cost;
        break;
      }
      if (anscost <= atop.cost)
        break;
      que.pop();

      for (int i = 0; i < 4; ++i) {
        aa na(mo(atop, i));
        if (!mp.count(na.field) || mp[na.field] > na.cost) {
          mp[na.field] = na.cost;

          que.emplace(na);
        }
      }
    }
    cout << anscost << endl;
  }
  return 0;
}

Error: MLE

Fixed submission:

#include "bits/stdc++.h"
#include <unordered_map>
#pragma warning(disable : 4996)
using namespace std;

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

int cost[2];

struct aa {
  vector<vector<short>> field;
  short voy : 4;
  short vox : 4;
  int cost;
};
aa mo(aa a, const int way) {
  const int ncost(a.cost + cost[way % 2]);
  short frx = a.vox + dx[way];
  short fry = a.voy + dy[way];
  if (frx < 0) {
    frx += 3;
    fry -= 1;
  } else if (frx >= 3) {
    frx -= 3;
    fry += 1;
  }
  if (fry < 0) {
    fry += 3;
  } else if (fry >= 3) {
    fry -= 3;
  }
  swap(a.field[a.voy][a.vox], a.field[fry][frx]);
  a.voy = fry;
  a.vox = frx;
  a.cost = ncost;
  return a;
}
class Compare {
public:
  // keiroが昇順に並ぶ
  bool operator()(const aa &l, const aa &r) { return l.cost > r.cost; }
};
class HashVI { // ハッシュ関数オブジェクト
public:
  size_t operator()(const vector<int> &x) const {
    const int C = 997; // 素数
    size_t t = 0;
    for (int i = 0; i != x.size(); ++i) {
      t = t * C + x[i];
    }
    return t;
  }
  size_t operator()(const vector<vector<int>> &x) const {
    const int C = 997; // 素数
    size_t t = 0;
    for (int i = 0; i != x.size(); ++i) {
      for (int j = 0; j < x[i].size(); ++j) {
        t = t * C + x[i][j];
      }
    }
    return t;
  }
  size_t operator()(const vector<vector<short>> &x) const {
    const int C = 9; // 素数
    size_t t = 0;
    for (int i = 0; i != x.size(); ++i) {
      for (int j = 0; j < x[i].size(); ++j) {
        t = t * C + x[i][j];
      }
    }
    return t;
  }
};

unordered_map<vector<vector<short>>, int, HashVI> mp;

int main() {
  while (1) {
    mp.clear();
    cin >> cost[0] >> cost[1];
    if (!cost[0] && !cost[1])
      break;
    short vx, vy;
    vector<vector<short>> field(3, vector<short>(3));
    for (int y = 0; y < 3; ++y) {
      for (int x = 0; x < 3; ++x) {
        int a;
        cin >> a;
        if (!a) {
          vx = x;
          vy = y;
        }
        field[y][x] = a;
      }
    }
    vector<vector<short>> ans(3, vector<short>(3));
    for (int y = 0; y < 3; ++y) {
      for (int x = 0; x < 3; ++x) {
        int a;
        cin >> a;
        ans[y][x] = a;
      }
    }
    priority_queue<aa, vector<aa>, Compare> que;
    que.push(aa{field, vy, vx, 0});

    int anscost = 0;
    if (field == ans) {
    } else {
      anscost = 999999;
      while (!que.empty()) {
        aa atop(que.top());
        if (atop.field == ans) {
          anscost = atop.cost;
          break;
        }
        if (anscost <= atop.cost)
          break;
        que.pop();

        for (int i = 0; i < 4; ++i) {
          aa na(mo(atop, i));
          if (!mp.count(na.field) || mp[na.field] > na.cost) {
            mp[na.field] = na.cost;

            que.emplace(na);
          }
        }
      }
    }
    cout << anscost << endl;
  }
  return 0;
}