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

#include <bits/stdc++.h>
using namespace std;
long long esp_org, esp_new;

int N;

struct P {
  int x, y, z;
  int dist(P p) { return abs(x - p.x) + abs(y - p.y) + abs(z - p.z); }
  P rotZ() { return {y, N - x - 1, z}; }
  P rotY() { return {z, y, N - x - 1}; }
  P rotX() { return {x, z, N - y - 1}; }

  bool valid() {
    if (x < 0 || x >= N)
      return false;
    if (y < 0 || y >= N)
      return false;
    if (z < 0 || z >= N)
      return false;
    return true;
  }
  string toString() {
    stringstream ss;
    ss << "(" << x << " " << y << " " << z << ")";
    return ss.str();
  }
};
bool operator<(const P &a, const P &b) {
  if (a.x != b.x)
    return a.x < b.x;
  if (a.y != b.y)
    return a.y < b.y;
  return a.z < b.z;
}
bool operator==(const P &a, const P &b) {
  if (a.x != b.x)
    return false;
  if (a.y != b.y)
    return false;
  return a.z == b.z;
}

P operator+(P a, P b) {
  a.x += b.x;
  a.y += b.y;
  a.z += b.z;
  return a;
};

struct NODE {
  vector<P> p;
  int phase;
  int cost;
};
bool operator<(const NODE &a, const NODE &b) {
  if (a.phase != b.phase)
    return a.phase < b.phase;
  return a.p < b.p;
}

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

vector<P> rot(vector<P> p, int id) {

  if (id == 0) {
    if (p[0].z == p[1].z)
      return p;
    p[0] = p[0].rotZ();
  }
  if (id == 1) {
    if (p[0].y == p[1].y)
      return p;
    p[0] = p[0].rotY();
  }
  if (id == 2) {
    if (p[0].x == p[1].x)
      return p;
    p[0] = p[0].rotX();
  }
  if (id == 3) {
    if (p[0].z == p[1].z)
      return p;
    p[0] = p[0].rotZ().rotZ().rotZ();
  }
  if (id == 4) {
    if (p[0].y == p[1].y)
      return p;
    p[0] = p[0].rotY().rotY().rotY();
  }
  if (id == 5) {
    if (p[0].x == p[1].x)
      return p;
    p[0] = p[0].rotX().rotX().rotX();
  }
  return p;
}

int main() {
  cin >> N;
  vector<P> c;
  for (int i = 0; i < 2; i++) {
    int x, y, z;
    cin >> x >> y >> z;
    c.push_back({x, y, z});
  }
  // c.resize(2);
  // N = 100000;
  // c[0] = {0,0,0};
  // c[1] = {N-1,N-1,N-1};

  // assert(c[0].rotY().rotY().rotY().rotY() == c[0]);
  // assert(c[1].rotZ().rotZ().rotZ().rotZ() == c[1]);
  // assert(c[1].rotX().rotX().rotX().rotX() == c[1]);

  map<NODE, int> done;

  deque<NODE> Q;

  int ans = 1e9;
  Q.push_back({c, 0, 0});
  int count = 0;
  while (Q.size()) {
    NODE q = Q.front();
    Q.pop_front();
    count++;
    if (done[q]++)
      continue;
    // cout << q.phase << "|" << q.p[0].toString() << " " << q.p[1].toString()
    // << "|" << q.cost << endl;
    ans = min(ans, q.cost + q.p[0].dist(q.p[1]));
    if (q.phase == 2)
      continue;

    if (q.phase == 0) {
      for (int i = 0; i < 6; i++) {
        P ne = q.p[0] + P{dx[i], dy[i], dz[i]};
        if (!ne.valid())
          continue;

        NODE nextq = q;
        nextq.cost++;
        nextq.p[0] = ne;
        nextq.phase++;
        if (!done[nextq])
          Q.push_back(nextq);
      }
    } else if (q.phase == 1) {
      for (int i = 0; i < 6; i++) {
        NODE nextq = q;
        nextq.cost++;
        nextq.p = rot(nextq.p, i);
        if (!done[nextq])
          Q.push_back(nextq);
      }
    }
    // next phase
    q.phase++;
    if (!done[q])
      Q.push_front(q);
  }
  // cout << count << endl;
  // cout << done.size() << "|" << count << endl;
  cout << ans << endl;
}

Error: MLE

Fixed submission:

#include <bits/stdc++.h>
using namespace std;
long long esp_org, esp_new;

int N;

struct P {
  int x, y, z;
  int dist(P p) { return abs(x - p.x) + abs(y - p.y) + abs(z - p.z); }
  P rotZ() { return {y, N - x - 1, z}; }
  P rotY() { return {z, y, N - x - 1}; }
  P rotX() { return {x, z, N - y - 1}; }

  bool valid() {
    if (x < 0 || x >= N)
      return false;
    if (y < 0 || y >= N)
      return false;
    if (z < 0 || z >= N)
      return false;
    return true;
  }
  string toString() {
    stringstream ss;
    ss << "(" << x << " " << y << " " << z << ")";
    return ss.str();
  }
};
bool operator<(const P &a, const P &b) {
  if (a.x != b.x)
    return a.x < b.x;
  if (a.y != b.y)
    return a.y < b.y;
  return a.z < b.z;
}
bool operator==(const P &a, const P &b) {
  if (a.x != b.x)
    return false;
  if (a.y != b.y)
    return false;
  return a.z == b.z;
}

P operator+(P a, P b) {
  a.x += b.x;
  a.y += b.y;
  a.z += b.z;
  return a;
};

struct NODE {
  vector<P> p;
  int phase;
  int cost;
};
bool operator<(const NODE &a, const NODE &b) {
  if (a.phase != b.phase)
    return a.phase < b.phase;
  return a.p < b.p;
}

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

vector<P> rot(vector<P> p, int id) {

  if (id == 0) {
    if (p[0].z == p[1].z)
      return p;
    p[0] = p[0].rotZ();
  }
  if (id == 1) {
    if (p[0].y == p[1].y)
      return p;
    p[0] = p[0].rotY();
  }
  if (id == 2) {
    if (p[0].x == p[1].x)
      return p;
    p[0] = p[0].rotX();
  }
  if (id == 3) {
    if (p[0].z == p[1].z)
      return p;
    p[0] = p[0].rotZ().rotZ().rotZ();
  }
  if (id == 4) {
    if (p[0].y == p[1].y)
      return p;
    p[0] = p[0].rotY().rotY().rotY();
  }
  if (id == 5) {
    if (p[0].x == p[1].x)
      return p;
    p[0] = p[0].rotX().rotX().rotX();
  }
  return p;
}

int main() {
  cin >> N;
  vector<P> c;
  for (int i = 0; i < N; i++) {
    int x, y, z;
    cin >> x >> y >> z;
    c.push_back({x, y, z});
  }
  // c.resize(2);
  // N = 100000;
  // c[0] = {0,0,0};
  // c[1] = {N-1,N-1,N-1};

  // assert(c[0].rotY().rotY().rotY().rotY() == c[0]);
  // assert(c[1].rotZ().rotZ().rotZ().rotZ() == c[1]);
  // assert(c[1].rotX().rotX().rotX().rotX() == c[1]);

  map<NODE, int> done;

  deque<NODE> Q;

  int ans = 1e9;
  Q.push_back({c, 0, 0});
  int count = 0;
  while (Q.size()) {
    NODE q = Q.front();
    Q.pop_front();
    count++;
    if (done[q]++)
      continue;
    // cout << q.phase << "|" << q.p[0].toString() << " " << q.p[1].toString()
    // << "|" << q.cost << endl;
    ans = min(ans, q.cost + q.p[0].dist(q.p[1]));
    if (q.phase == 2)
      continue;

    if (q.phase == 0) {
      for (int i = 0; i < 6; i++) {
        P ne = q.p[0] + P{dx[i], dy[i], dz[i]};
        if (!ne.valid())
          continue;

        NODE nextq = q;
        nextq.cost++;
        nextq.p[0] = ne;
        nextq.phase++;
        if (!done[nextq])
          Q.push_back(nextq);
      }
    } else if (q.phase == 1) {
      for (int i = 0; i < 6; i++) {
        NODE nextq = q;
        nextq.cost++;
        nextq.p = rot(nextq.p, i);
        if (!done[nextq])
          Q.push_back(nextq);
      }
    }
    // next phase
    q.phase++;
    if (!done[q])
      Q.push_front(q);
  }
  // cout << count << endl;
  // cout << done.size() << endl;
  cout << ans << endl;
}