Problem p00762 (C++)

Buggy submission (status: Memory Limit Exceeded):
#include <bits/stdc++.h>
using namespace std;

const int xRoll[4] = {0, 2, 5, 3};
const int yRoll[4] = {0, 4, 5, 1};
const int zRoll[4] = {1, 2, 4, 3};
const int dx[4] = {0, 1, 0, -1};
const int dy[4] = {-1, 0, 1, 0};
struct Dice {
  bool empty = true;
  vector<int> num;
  void rotate(int dir) {
    if (dx[dir] == 0) {
      rotateY(dy[dir]);
    } else {
      rotateX(dx[dir]);
    }
  }
  void rotateX(int dir) {
    int tmp[6];
    for (int i = 0; i < 6; i++)
      tmp[i] = num[i];
    for (int i = 0; i < 4; i++) {
      tmp[xRoll[i]] = num[xRoll[(i - dir + 4) % 4]];
    }
    for (int i = 0; i < 6; i++)
      num[i] = tmp[i];
  }
  void rotateY(int dir) {
    int tmp[6];
    for (int i = 0; i < 6; i++)
      tmp[i] = num[i];
    for (int i = 0; i < 4; i++) {
      tmp[yRoll[i]] = num[yRoll[(i - dir + 4) % 4]];
    }
    for (int i = 0; i < 6; i++)
      num[i] = tmp[i];
  }
  Dice() : empty(true), num(6){};
  Dice(int t, int f) : num(6) {
    empty = false;
    num[0] = t;
    num[2] = f;
    num[5] = 5 - t;
    num[3] = 5 - f;
    for (int i = 0; i < 4; i++) {
      if (xRoll[i] == t && xRoll[(i + 1) % 4] == f) {
        num[1] = 1;
        num[4] = 4;
        return;
      }
      if (xRoll[i] == t && xRoll[(i - 1 + 4) % 4] == f) {
        num[1] = 4;
        num[4] = 1;
        return;
      }
    }
    for (int i = 0; i < 4; i++) {
      if (yRoll[i] == t && yRoll[(i + 1) % 4] == f) {
        num[1] = 2;
        num[4] = 3;
        return;
      }
      if (yRoll[i] == t && yRoll[(i - 1 + 4) % 4] == f) {
        num[1] = 3;
        num[4] = 2;
        return;
      }
    }
    for (int i = 0; i < 4; i++) {
      if (zRoll[i] == t && zRoll[(i + 1) % 4] == f) {
        num[1] = 5;
        num[4] = 0;
        return;
      }
      if (zRoll[i] == t && zRoll[(i - 1 + 4) % 4] == f) {
        num[1] = 0;
        num[4] = 5;
        return;
      }
    }
  }
};
const int SIZE = 220;
const int HEIGHT = 60;
const int iniX = 110;
const int iniY = 110;

struct Field {
  vector<vector<vector<Dice>>> f;
  void drop_impl(int posX, int posY, int posZ, Dice x) {
    if (posZ == 0) {
      f[posX][posY][posZ] = x;
      return;
    }
    pair<int, int> dir = make_pair(-1, -1);
    for (int i = 0; i < 4; i++) {
      int toX = posX + dx[i];
      int toY = posY + dy[i];
      if (f[toX][toY][posZ - 1].empty) {
        dir = max(dir, make_pair(x.num[zRoll[i]], i));
      }
    }
    if (dir.first < 3) {
      f[posX][posY][posZ] = x;
      return;
    }
    x.rotate(dir.second);
    posX += dx[dir.second];
    posY += dy[dir.second];
    for (int i = posZ; i >= 0; i--) {
      if (!f[posX][posY][i].empty) {
        drop_impl(posX, posY, i + 1, x);
        return;
      }
    }
    drop_impl(posX, posY, 0, x);
  }

public:
  Field() : f(SIZE, vector<vector<Dice>>(SIZE, vector<Dice>(HEIGHT))){};
  void drop(Dice x) {
    for (int i = HEIGHT - 1; i >= 0; i--) {
      if (!f[iniX][iniY][i].empty) {
        drop_impl(iniX, iniY, i + 1, x);
        return;
      }
    }
    drop_impl(iniX, iniY, 0, x);
  }

  void query() {
    vector<int> cnt(6, 0);
    for (int x = 0; x < SIZE; x++) {
      for (int y = 0; y < SIZE; y++) {
        for (int z = HEIGHT - 1; z >= 0; z--) {
          if (!f[x][y][z].empty) {
            cnt[f[x][y][z].num[0]]++;
            break;
          }
        }
      }
    }
    for (int i = 0; i < 6; i++) {
      cout << cnt[i] << (i == 5 ? "\n" : " ");
    }
  }
};

int main() {
  int n;
  while (cin >> n, n) {
    Field ff;
    for (int i = 0; i < n; i++) {
      int t, f;
      cin >> t >> f;
      t--, f--;
      Dice x(t, f);
      ff.drop(Dice(t, f));
    }
    ff.query();
  }
  return 0;
}


Fixed submission:
#include <bits/stdc++.h>
using namespace std;

const int xRoll[4] = {0, 2, 5, 3};
const int yRoll[4] = {0, 4, 5, 1};
const int zRoll[4] = {1, 2, 4, 3};
const int dx[4] = {0, 1, 0, -1};
const int dy[4] = {-1, 0, 1, 0};
struct Dice {
  bool empty = true;
  vector<int> num;
  void rotate(int dir) {
    if (dx[dir] == 0) {
      rotateY(dy[dir]);
    } else {
      rotateX(dx[dir]);
    }
  }
  void rotateX(int dir) {
    int tmp[6];
    for (int i = 0; i < 6; i++)
      tmp[i] = num[i];
    for (int i = 0; i < 4; i++) {
      tmp[xRoll[i]] = num[xRoll[(i - dir + 4) % 4]];
    }
    for (int i = 0; i < 6; i++)
      num[i] = tmp[i];
  }
  void rotateY(int dir) {
    int tmp[6];
    for (int i = 0; i < 6; i++)
      tmp[i] = num[i];
    for (int i = 0; i < 4; i++) {
      tmp[yRoll[i]] = num[yRoll[(i - dir + 4) % 4]];
    }
    for (int i = 0; i < 6; i++)
      num[i] = tmp[i];
  }
  Dice() : empty(true), num(0){};
  Dice(int t, int f) : num(6) {
    empty = false;
    num[0] = t;
    num[2] = f;
    num[5] = 5 - t;
    num[3] = 5 - f;
    for (int i = 0; i < 4; i++) {
      if (xRoll[i] == t && xRoll[(i + 1) % 4] == f) {
        num[1] = 1;
        num[4] = 4;
        return;
      }
      if (xRoll[i] == t && xRoll[(i - 1 + 4) % 4] == f) {
        num[1] = 4;
        num[4] = 1;
        return;
      }
    }
    for (int i = 0; i < 4; i++) {
      if (yRoll[i] == t && yRoll[(i + 1) % 4] == f) {
        num[1] = 2;
        num[4] = 3;
        return;
      }
      if (yRoll[i] == t && yRoll[(i - 1 + 4) % 4] == f) {
        num[1] = 3;
        num[4] = 2;
        return;
      }
    }
    for (int i = 0; i < 4; i++) {
      if (zRoll[i] == t && zRoll[(i + 1) % 4] == f) {
        num[1] = 5;
        num[4] = 0;
        return;
      }
      if (zRoll[i] == t && zRoll[(i - 1 + 4) % 4] == f) {
        num[1] = 0;
        num[4] = 5;
        return;
      }
    }
  }
};
const int SIZE = 220;
const int HEIGHT = 60;
const int iniX = 110;
const int iniY = 110;

struct Field {
  vector<vector<vector<Dice>>> f;
  void drop_impl(int posX, int posY, int posZ, Dice x) {
    if (posZ == 0) {
      f[posX][posY][posZ] = x;
      return;
    }
    pair<int, int> dir = make_pair(-1, -1);
    for (int i = 0; i < 4; i++) {
      int toX = posX + dx[i];
      int toY = posY + dy[i];
      if (f[toX][toY][posZ - 1].empty) {
        dir = max(dir, make_pair(x.num[zRoll[i]], i));
      }
    }
    if (dir.first < 3) {
      f[posX][posY][posZ] = x;
      return;
    }
    x.rotate(dir.second);
    posX += dx[dir.second];
    posY += dy[dir.second];
    for (int i = posZ; i >= 0; i--) {
      if (!f[posX][posY][i].empty) {
        drop_impl(posX, posY, i + 1, x);
        return;
      }
    }
    drop_impl(posX, posY, 0, x);
  }

public:
  Field() : f(SIZE, vector<vector<Dice>>(SIZE, vector<Dice>(HEIGHT))){};
  void drop(Dice x) {
    for (int i = HEIGHT - 1; i >= 0; i--) {
      if (!f[iniX][iniY][i].empty) {
        drop_impl(iniX, iniY, i + 1, x);
        return;
      }
    }
    drop_impl(iniX, iniY, 0, x);
  }

  void query() {
    vector<int> cnt(6, 0);
    for (int x = 0; x < SIZE; x++) {
      for (int y = 0; y < SIZE; y++) {
        for (int z = HEIGHT - 1; z >= 0; z--) {
          if (!f[x][y][z].empty) {
            cnt[f[x][y][z].num[0]]++;
            break;
          }
        }
      }
    }
    for (int i = 0; i < 6; i++) {
      cout << cnt[i] << (i == 5 ? "\n" : " ");
    }
  }
};

int main() {
  int n;
  while (cin >> n, n) {
    Field ff;
    for (int i = 0; i < n; i++) {
      int t, f;
      cin >> t >> f;
      t--, f--;
      Dice x(t, f);
      ff.drop(Dice(t, f));
    }
    ff.query();
  }
  return 0;
}