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

/*
 * C.cpp
 *
 *  Created on: 2017/06/18
 *      Author: aihara
 */

#include <bits/stdc++.h>
#define MYDEBUG
#ifdef MYDBUG
#define dbp(x) cout << #x << ": " << x << endl
#else
#define dbp(x)
#endif
#define ll long long
#define rep(i, from, to) for (int i = from; i < to; ++i)
#define REP(i, from, to) for (int i = from; i <= to; ++i)

using namespace std;
int B[7] = {0, 6, 5, 4, 3, 2, 1};
int L[7][7] = {{0, 0, 0, 0, 0, 0, 0}, {0, 0, 3, 5, 2, 4, 0},
               {0, 4, 0, 1, 6, 0, 3}, {0, 2, 6, 0, 0, 1, 5},
               {0, 5, 1, 0, 0, 6, 2}, {0, 3, 0, 6, 1, 0, 4},
               {0, 0, 4, 2, 5, 3, 0}};
int di[4] = {1, 0, -1, 0}; // down, left, up, right
int dj[4] = {0, -1, 0, 1};
struct die {
  int num[6];
  die() { *this = die(0, 0, 0, 0, 0, 0); }
  die(int t_, int d_, int l_, int u_, int r_, int b_) {
    num[0] = t_;
    num[1] = d_;
    num[2] = l_;
    num[3] = u_;
    num[4] = r_;
    num[5] = b_;
  }
  int top() { return num[0]; }
  int down() { return num[1]; }
  int left() { return num[2]; }
  int up() { return num[3]; }
  int right() { return num[4]; }
  int back() { return num[5]; }

  void move(int dir) {
    if (dir == 0) {
      moveD();
    } else if (dir == 1) {
      moveL();
    } else if (dir == 2) {
      moveU();
    } else if (dir == 3) {
      moveR();
    }
  }
  void moveL() {
    int tmp = num[0];
    num[0] = num[4];
    num[4] = num[5];
    num[5] = num[2];
    num[2] = tmp;
  }

  void moveU() {
    int tmp = num[0];
    num[0] = num[1];
    num[1] = num[5];
    num[5] = num[3];
    num[3] = tmp;
  }

  void moveR() {
    int tmp = num[0];
    num[0] = num[2];
    num[2] = num[5];
    num[5] = num[4];
    num[4] = tmp;
  }

  void moveD() {
    int tmp = num[0];
    num[0] = num[3];
    num[3] = num[5];
    num[5] = num[1];
    num[1] = tmp;
  }
};
typedef struct die die;
const int MAX_N = 101;
die box[MAX_N][MAX_N][MAX_N];
int height[MAX_N][MAX_N];
int ans[7];
void init() {
  memset(height, 0, sizeof(height));
  memset(ans, 0, sizeof(ans));
  rep(i, 0, MAX_N) {
    rep(j, 0, MAX_N) {
      rep(k, 0, MAX_N) { box[i][j][k] = die(); }
    }
  }
}

bool ok(int i, int j, int k, int dir, die die) {
  int ni = i + di[dir];
  int nj = j + dj[dir];
  int nk = k - 1;
  int num = die.num[1 + dir];
  //	printf("%d %d %d %d\\n", i, j, k, dir);
  return 0 <= nk && 4 <= num && num <= 6 && box[ni][nj][nk].num[0] == 0 &&
         box[ni][nj][k].num[0] == 0;
}

// void printdb() {
//	REP(i,95, 105)
//	{
//		REP(j, 95, 105)
//		{
//			int h = height[i][j];
//			cout << box[i][j][h - 1].num[0] << " ";
//		}
//		cout << endl;
//	}
// }

void simulate(int t, int d) {
  //	printdb();
  //	cout << "???" << endl;
  int i = MAX_N / 2;
  int j = MAX_N / 2;
  int k = height[i][j];
  // t,d,l,u,r,b
  box[i][j][k] = die(t, d, L[d][t], B[d], B[L[d][t]], B[t]);
  height[i][j]++;
  bool moved = true;
  while (moved) {
    moved = false;
    int nextDir = -1, maxSide = -1;
    k = height[i][j] - 1;
    rep(dir, 0, 4) {
      if (ok(i, j, k, dir, box[i][j][k])) {
        if (maxSide < box[i][j][k].num[1 + dir]) {
          nextDir = dir;
          maxSide = box[i][j][k].num[1 + dir];
        }
      }
    }
    if (nextDir != -1) {
      moved = true;
      box[i][j][k].move(nextDir);
      int ni = i + di[nextDir];
      int nj = j + dj[nextDir];
      int nk = height[ni][nj];
      box[ni][nj][nk] = box[i][j][k];
      box[i][j][k] = die();
      height[i][j]--;
      height[ni][nj]++;
      i = ni;
      j = nj;

    } else {
      break;
    }
  }
  //	printdb();
  //	cout << endl;
}

void count() {
  rep(i, 0, MAX_N) {
    rep(j, 0, MAX_N) {
      int h = height[i][j];
      if (h == 0) {
        continue;
      }
      int top = box[i][j][h - 1].num[0];
      ans[top]++;
    }
  }
}

int n, t, f;
void solve() {
  while (cin >> n, n) {
    init();
    rep(die_index, 0, n) {
      cin >> t >> f;
      // t,d,l,u,r,b
      simulate(t, f);
    }
    count();
    REP(i, 1, 5) { cout << ans[i] << " "; }
    cout << ans[6] << endl;
  }
}

int main() {
  solve();
  //	t = 6;
  //	int d = 4;
  //	die di = die(t, d, L[d][t], B[d], B[L[d][t]], B[t]);
  //	printf("%d, %d, %d, %d, %d, %d\\n", di.top(), di.down(), di.left(),
  //di.up(), 			di.right(), di.back());
}

Error: MLE

Fixed submission:

/*
 * C.cpp
 *
 *  Created on: 2017/06/18
 *      Author: aihara
 */

#include <bits/stdc++.h>
#define MYDEBUG
#ifdef MYDBUG
#define dbp(x) cout << #x << ": " << x << endl
#else
#define dbp(x)
#endif
#define ll long long
#define rep(i, from, to) for (int i = from; i < to; ++i)
#define REP(i, from, to) for (int i = from; i <= to; ++i)

using namespace std;
int B[7] = {0, 6, 5, 4, 3, 2, 1};
int L[7][7] = {{0, 0, 0, 0, 0, 0, 0}, {0, 0, 3, 5, 2, 4, 0},
               {0, 4, 0, 1, 6, 0, 3}, {0, 2, 6, 0, 0, 1, 5},
               {0, 5, 1, 0, 0, 6, 2}, {0, 3, 0, 6, 1, 0, 4},
               {0, 0, 4, 2, 5, 3, 0}};
int di[4] = {1, 0, -1, 0}; // down, left, up, right
int dj[4] = {0, -1, 0, 1};
struct die {
  int num[6];
  die() { *this = die(0, 0, 0, 0, 0, 0); }
  die(int t_, int d_, int l_, int u_, int r_, int b_) {
    num[0] = t_;
    num[1] = d_;
    num[2] = l_;
    num[3] = u_;
    num[4] = r_;
    num[5] = b_;
  }
  int top() { return num[0]; }
  int down() { return num[1]; }
  int left() { return num[2]; }
  int up() { return num[3]; }
  int right() { return num[4]; }
  int back() { return num[5]; }

  void move(int dir) {
    if (dir == 0) {
      moveD();
    } else if (dir == 1) {
      moveL();
    } else if (dir == 2) {
      moveU();
    } else if (dir == 3) {
      moveR();
    }
  }
  void moveL() {
    int tmp = num[0];
    num[0] = num[4];
    num[4] = num[5];
    num[5] = num[2];
    num[2] = tmp;
  }

  void moveU() {
    int tmp = num[0];
    num[0] = num[1];
    num[1] = num[5];
    num[5] = num[3];
    num[3] = tmp;
  }

  void moveR() {
    int tmp = num[0];
    num[0] = num[2];
    num[2] = num[5];
    num[5] = num[4];
    num[4] = tmp;
  }

  void moveD() {
    int tmp = num[0];
    num[0] = num[3];
    num[3] = num[5];
    num[5] = num[1];
    num[1] = tmp;
  }
};
typedef struct die die;
const int MAX_N = 201;
die box[MAX_N][MAX_N][MAX_N];
int height[MAX_N][MAX_N];
int ans[7];
void init() {
  memset(height, 0, sizeof(height));
  memset(ans, 0, sizeof(ans));
  rep(i, 0, MAX_N) {
    rep(j, 0, MAX_N) {
      rep(k, 0, MAX_N) { box[i][j][k] = die(); }
    }
  }
}

bool ok(int i, int j, int k, int dir, die die) {
  int ni = i + di[dir];
  int nj = j + dj[dir];
  int nk = k - 1;
  int num = die.num[1 + dir];
  //	printf("%d %d %d %d\\n", i, j, k, dir);
  return 0 <= nk && 4 <= num && num <= 6 && box[ni][nj][nk].num[0] == 0 &&
         box[ni][nj][k].num[0] == 0;
}

void printdb() {
  REP(i, 95, 105) {
    REP(j, 95, 105) {
      int h = height[i][j];
      cout << box[i][j][h - 1].num[0] << " ";
    }
    cout << endl;
  }
}

void simulate(int t, int d) {
  //	printdb();
  //	cout << "???" << endl;
  int i = MAX_N / 2;
  int j = MAX_N / 2;
  int k = height[i][j];
  // t,d,l,u,r,b
  box[i][j][k] = die(t, d, L[d][t], B[d], B[L[d][t]], B[t]);
  height[i][j]++;
  bool moved = true;
  while (moved) {
    moved = false;
    int nextDir = -1, maxSide = -1;
    k = height[i][j] - 1;
    rep(dir, 0, 4) {
      if (ok(i, j, k, dir, box[i][j][k])) {
        if (maxSide < box[i][j][k].num[1 + dir]) {
          nextDir = dir;
          maxSide = box[i][j][k].num[1 + dir];
        }
      }
    }
    if (nextDir != -1) {
      moved = true;
      box[i][j][k].move(nextDir);
      int ni = i + di[nextDir];
      int nj = j + dj[nextDir];
      int nk = height[ni][nj];
      box[ni][nj][nk] = box[i][j][k];
      box[i][j][k] = die();
      height[i][j]--;
      height[ni][nj]++;
      i = ni;
      j = nj;

    } else {
      break;
    }
  }
  //	printdb();
  //	cout << endl;
}

void count() {
  rep(i, 0, MAX_N) {
    rep(j, 0, MAX_N) {
      int h = height[i][j];
      if (h == 0) {
        continue;
      }
      int top = box[i][j][h - 1].num[0];
      ans[top]++;
    }
  }
}

int n, t, f;
void solve() {
  while (cin >> n, n) {
    init();
    rep(die_index, 0, n) {
      cin >> t >> f;
      // t,d,l,u,r,b
      simulate(t, f);
    }
    count();
    REP(i, 1, 5) { cout << ans[i] << " "; }
    cout << ans[6] << endl;
  }
}

int main() {
  solve();
  //	t = 6;
  //	int d = 4;
  //	die di = die(t, d, L[d][t], B[d], B[L[d][t]], B[t]);
  //	printf("%d, %d, %d, %d, %d, %d\\n", di.top(), di.down(), di.left(),
  //di.up(), 			di.right(), di.back());
}