Problem p01362 (C++)

Buggy submission (status: Runtime Error):
#include <algorithm>
#include <bitset>
#include <cassert>
#include <climits>
#include <cmath>
#include <complex>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <iomanip>
#include <iostream>
#include <map>
#include <queue>
#include <set>
#include <sstream>
#include <stack>
#include <string>
#include <valarray>
#include <vector>
using namespace std;

#define REP(i, n) for (int i = 0; i < (int)n; ++i)
#define FOR(i, c)                                                              \
  for (__typeof((c).begin()) i = (c).begin(); i != (c).end(); ++i)
#define ALL(c) (c).begin(), (c).end()
typedef long long ll;
typedef pair<int, int> pii;
const int INF = 1 << 29;
const double PI = acos(-1);
const double EPS = 1e-8;

template <class T> struct dice {
  T t, b, n, s, e, w; // top bottom north south east west
  int dir[6];         // directions of each face
  dice() {}
  dice(T t, T b, T n, T s, T e, T w) : t(t), b(b), n(n), s(s), e(e), w(w) {
    REP(i, 6) dir[i] = 0;
  }
  void roll(T &a, T &b, T &c, T &d) {
    swap(a, b);
    swap(b, c);
    swap(c, d);
  }
  void roll_x() {
    roll(t, n, b, s);
    int tmp[6];
    tmp[0] = dir[4];
    tmp[1] = (dir[1] + 1) % 4;
    tmp[2] = (dir[5] + 2) % 4;
    tmp[3] = (dir[3] + 3) % 4;
    tmp[4] = (dir[2] + 2) % 4;
    tmp[5] = dir[0];
    REP(i, 6) dir[i] = tmp[i];
  }
  void roll_y() {
    roll(t, w, b, e);
    int tmp[6];
    tmp[0] = (dir[0] + 3) % 4;
    tmp[1] = (dir[4] + 3) % 4;
    tmp[2] = (dir[2] + 1) % 4;
    tmp[3] = (dir[5] + 3) % 4;
    tmp[4] = (dir[3] + 3) % 4;
    tmp[5] = (dir[1] + 3) % 4;
    REP(i, 6) dir[i] = tmp[i];
  }
  void roll_z() { roll(s, e, n, w); }
  vector<dice> all_rolls() {
    vector<dice> ret;
    for (int k = 0; k < 6; (k & 1 ? roll_y() : roll_x()), ++k)
      for (int i = 0; i < 4; roll_z(), ++i)
        ret.push_back(*this);
    return ret;
  }
  void toTable(int *res) {
    res[0] = t;
    res[1] = b;
    res[2] = n;
    res[3] = s;
    res[4] = e;
    res[5] = w;
  }
};

string face_str[6][3];
bool face[6][3][3];
dice<int> dicemp[6][6];
int dist[6][6];

bool func(int f, int d) {
  if (d == 0) {
    return face[f][2][0] || face[f][2][1] || face[f][2][2];
  } else if (d == 1) {
    return face[f][0][0] || face[f][1][0] || face[f][2][0];
  } else if (d == 2) {
    return face[f][0][0] || face[f][0][1] || face[f][0][2];
  } else {
    return face[f][0][2] || face[f][1][2] || face[f][2][2];
  }
}

int main() {
  dice<int> di(4, 5, 2, 0, 1, 3);
  FOR(it, di.all_rolls()) { dicemp[it->t][it->s] = *it; }

  while (cin >> face_str[0][0], face_str[0][0] != "#") {
    REP(i, 2) cin >> face_str[0][i + 1];
    REP(i, 5) REP(j, 3) cin >> face_str[i + 1][j];
    REP(i, 6) REP(j, 3) REP(k, 3) {
      face[i][j][k] = (face_str[i][j][k] == '*');
    }

    queue<pii> Q;
    Q.push(pii(di.t, di.s));
    memset(dist, -1, sizeof(dist));
    dist[di.t][di.s] = 0;
    int ans = -1;
    while (!Q.empty()) {
      pii p = Q.front();
      Q.pop();
      dice<int> now = dicemp[p.first][p.second];
      int d = dist[now.t][now.s];

      if (func(now.s, now.dir[0]) && func(now.n, now.dir[2])) {
        ans = d;
        break;
      }

      dice<int> tmp = now;
      REP(i, 2) {
        tmp.roll_x();
        if (dist[tmp.t][tmp.s] == -1) {
          dist[tmp.t][tmp.s] = d + 1;
          Q.push(pii(tmp.t, tmp.s));
        }
        tmp.roll_x();
      }
      tmp = now;
      REP(i, 2) {
        tmp.roll_y();
        if (dist[tmp.t][tmp.s] == -1) {
          dist[tmp.t][tmp.s] = d + 1;
          Q.push(pii(tmp.t, tmp.s));
        }
        tmp.roll_y();
      }
    }
    assert(ans != -1);
    cout << ans << endl;
  }
}

Fixed submission:
#include <algorithm>
#include <bitset>
#include <cassert>
#include <climits>
#include <cmath>
#include <complex>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <iomanip>
#include <iostream>
#include <map>
#include <queue>
#include <set>
#include <sstream>
#include <stack>
#include <string>
#include <valarray>
#include <vector>
using namespace std;

#define REP(i, n) for (int i = 0; i < (int)n; ++i)
#define FOR(i, c)                                                              \
  for (__typeof((c).begin()) i = (c).begin(); i != (c).end(); ++i)
#define ALL(c) (c).begin(), (c).end()
typedef long long ll;
typedef pair<int, int> pii;
const int INF = 1 << 29;
const double PI = acos(-1);
const double EPS = 1e-8;

template <class T> struct dice {
  T t, b, n, s, e, w; // top bottom north south east west
  int dir[6];         // directions of each face
  dice() {}
  dice(T t, T b, T n, T s, T e, T w) : t(t), b(b), n(n), s(s), e(e), w(w) {
    REP(i, 6) dir[i] = 0;
  }
  void roll(T &a, T &b, T &c, T &d) {
    swap(a, b);
    swap(b, c);
    swap(c, d);
  }
  void roll_x() {
    roll(t, n, b, s);
    int tmp[6];
    tmp[0] = dir[4];
    tmp[1] = (dir[1] + 1) % 4;
    tmp[2] = (dir[5] + 2) % 4;
    tmp[3] = (dir[3] + 3) % 4;
    tmp[4] = (dir[2] + 2) % 4;
    tmp[5] = dir[0];
    REP(i, 6) dir[i] = tmp[i];
  }
  void roll_y() {
    roll(t, w, b, e);
    int tmp[6];
    tmp[0] = (dir[0] + 3) % 4;
    tmp[1] = (dir[4] + 3) % 4;
    tmp[2] = (dir[2] + 1) % 4;
    tmp[3] = (dir[5] + 3) % 4;
    tmp[4] = (dir[3] + 3) % 4;
    tmp[5] = (dir[1] + 3) % 4;
    REP(i, 6) dir[i] = tmp[i];
  }
  void roll_z() {
    roll(s, e, n, w);
    roll(dir[0], dir[1], dir[2], dir[3]);
    dir[4] = (dir[4] + 3) % 4;
    dir[5] = (dir[5] + 1) % 4;
  }
  vector<dice> all_rolls() {
    vector<dice> ret;
    for (int k = 0; k < 6; (k & 1 ? roll_y() : roll_x()), ++k)
      for (int i = 0; i < 4; roll_z(), ++i)
        ret.push_back(*this);
    return ret;
  }
  void toTable(int *res) {
    res[0] = t;
    res[1] = b;
    res[2] = n;
    res[3] = s;
    res[4] = e;
    res[5] = w;
  }
};

string face_str[6][3];
bool face[6][3][3];
dice<int> dicemp[6][6];
int dist[6][6];

bool func(int f, int d) {
  if (d == 0) {
    return face[f][2][0] || face[f][2][1] || face[f][2][2];
  } else if (d == 1) {
    return face[f][0][0] || face[f][1][0] || face[f][2][0];
  } else if (d == 2) {
    return face[f][0][0] || face[f][0][1] || face[f][0][2];
  } else {
    return face[f][0][2] || face[f][1][2] || face[f][2][2];
  }
}

int main() {
  dice<int> di(4, 5, 2, 0, 1, 3);
  FOR(it, di.all_rolls()) { dicemp[it->t][it->s] = *it; }

  while (cin >> face_str[0][0], face_str[0][0] != "#") {
    REP(i, 2) cin >> face_str[0][i + 1];
    REP(i, 5) REP(j, 3) cin >> face_str[i + 1][j];
    REP(i, 6) REP(j, 3) REP(k, 3) {
      face[i][j][k] = (face_str[i][j][k] == '*');
    }

    queue<pii> Q;
    Q.push(pii(di.t, di.s));
    memset(dist, -1, sizeof(dist));
    dist[di.t][di.s] = 0;
    int ans = -1;
    while (!Q.empty()) {
      pii p = Q.front();
      Q.pop();
      dice<int> now = dicemp[p.first][p.second];
      int d = dist[now.t][now.s];

      if (func(now.s, now.dir[0]) && func(now.n, now.dir[2])) {
        ans = d;
        break;
      }

      dice<int> tmp = now;
      REP(i, 2) {
        tmp.roll_x();
        if (dist[tmp.t][tmp.s] == -1) {
          dist[tmp.t][tmp.s] = d + 1;
          Q.push(pii(tmp.t, tmp.s));
        }
        tmp.roll_x();
      }
      tmp = now;
      REP(i, 2) {
        tmp.roll_y();
        if (dist[tmp.t][tmp.s] == -1) {
          dist[tmp.t][tmp.s] = d + 1;
          Q.push(pii(tmp.t, tmp.s));
        }
        tmp.roll_y();
      }
    }
    assert(ans != -1);
    cout << ans << endl;
  }
}