Problem p00171 (C++) — buggy submission, verdict: Time Limit Exceeded

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

// If this structure is used for two-dimensional surface,
// it assumes that the face id[0] faces the positive direction of the Y axis,
// the face id[1] faces the positive direction of the X axis
// and id[2] is top of the dice.
struct Dice {
  int id[6], cnt;
  const static int f[3][3];

  Dice() { init(); }

  void init() {
    for (int i = 0; i < 6; ++i) {
      id[i] = i;
    }
    cnt = 0;
  }

  // type (0:spin, 1:rollX, 2:rollY)
  // dir 1( ccw     neg      pos   )
  //    -1( cw      pos      neg   )
  void rotate(int type, int dir = 1) {
    const int *v = f[type];
    int a, b, c, t;
    a = v[0];
    b = v[1];
    c = v[2];
    t = id[type];
    if (dir < 0)
      swap(a, c);
    id[type] = id[a];
    id[a] = id[b];
    id[b] = id[c];
    id[c] = t;
  }

  bool next() {
    ++cnt;
    if (cnt == 24) {
      rotate(0, -1);
      rotate(1, -1);
      cnt = 0;
      return false;
    }
    if (cnt == 4 * 3) {
      rotate(2, -1);
      rotate(0, -1);
    } else if (cnt % 4 == 0) {
      rotate(2);
    } else {
      rotate(0);
    }
    return true;
  }

  void roll(int dir) {
    // const static int dx[] = {1,0,-1,0};
    // const static int dy[] = {0,1,0,-1};
    switch (dir) {
    case 0:
      rotate(1, -1);
      break;
    case 1:
      rotate(2, 1);
      break;
    case 2:
      rotate(1, 1);
      break;
    case 3:
      rotate(2, -1);
      break;
    }
  }

  bool operator<(const Dice &d) const {
    for (int i = 0; i < 3; ++i)
      if (id[i] != d.id[i])
        return id[i] < d.id[i];
    return false;
  }

  void show() {
    cout << id[4] << " / \\\\ " << id[5] << endl;
    cout << " /   \\\\" << endl;
    cout << "|\\\\ " << id[2] << " /|" << endl;
    cout << "|" << id[0] << "\\\\ /" << id[1] << "|" << endl;
    cout << " \\\\ | /" << endl;
    cout << "  \\\\|/" << endl;
    cout << "   " << id[3] << endl;
  }
};
const int Dice::f[3][3] = {{4, 5, 1}, {3, 4, 2}, {5, 3, 0}};

const int MAXN = 8;
vector<Dice> ds;
vector<string> F;
bool used[MAXN];
int G[2][2][2];
int S[2][2][2];

inline bool equals(char a, char b) {
  if (a > b)
    swap(a, b);
  return b - a == 'a' - 'A';
}

bool rec(int pos) {
  const static int X[8] = {0, 1, 0, 0, 1, 1, 0, 1};
  const static int Y[8] = {0, 0, 1, 0, 1, 0, 1, 1};
  const static int Z[8] = {0, 0, 0, 1, 0, 1, 1, 1};
  const static int dx[6] = {1, 0, 0, -1, 0, 0};
  const static int dy[6] = {0, 1, 0, 0, -1, 0};
  const static int dz[6] = {0, 0, 1, 0, 0, -1};
  const static int p[6] = {1, 0, 2, 4, 5, 3};

  if (pos == 8)
    return true;
  const int &x = X[pos];
  const int &y = Y[pos];
  const int &z = Z[pos];
  for (int i = 0; i < 8; ++i) {
    if (used[i])
      continue;
    used[i] = true;
    S[x][y][z] = i;
    for (int j = 0; j < ds.size(); ++j) {
      const Dice &s = ds[j];
      G[x][y][z] = j;
      bool flag = true;
      for (int k = 0; k < 6; ++k) {
        int nx = x + dx[k];
        int ny = y + dy[k];
        int nz = z + dz[k];
        if (nx < 0 || nx >= 2)
          continue;
        if (ny < 0 || ny >= 2)
          continue;
        if (nz < 0 || nz >= 2)
          continue;
        if (G[nx][ny][nz] == -1)
          continue;
        const Dice &t = ds[G[nx][ny][nz]];
        if (!equals(F[i][s.id[p[k]]], F[S[nx][ny][nz]][t.id[5 - p[k]]])) {
          flag = false;
          break;
        }
      }
      if (flag) {
        if (rec(pos + 1))
          return true;
      }
    }
    used[i] = false;
  }
  G[x][y][z] = -1;
  return false;
}

int main() {
  {
    Dice d;
    do {
      ds.push_back(d);
    } while (d.next());
  }
  F = vector<string>(8, string(6, ' '));
  while (1) {
    for (int i = 0; i < 8; ++i) {
      string s;
      cin >> s;
      if (s == "0")
        return 0;
      F[i][2] = s[0];
      F[i][0] = s[1];
      F[i][1] = s[2];
      F[i][4] = s[3];
      F[i][5] = s[4];
      F[i][3] = s[5];
    }
    fill(G[0][0], G[2][0], -1);
    fill(used, used + 8, false);
    if (rec(0))
      cout << "YES" << endl;
    else
      cout << "NO" << endl;
  }
  return 0;
}

Error: TLE

Fixed submission:

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

// If this structure is used for two-dimensional surface,
// it assumes that the face id[0] faces the positive direction of the Y axis,
// the face id[1] faces the positive direction of the X axis
// and id[2] is top of the dice.
struct Dice {
  int id[6], cnt;
  const static int f[3][3];

  Dice() { init(); }

  void init() {
    for (int i = 0; i < 6; ++i) {
      id[i] = i;
    }
    cnt = 0;
  }

  // type (0:spin, 1:rollX, 2:rollY)
  // dir 1( ccw     neg      pos   )
  //    -1( cw      pos      neg   )
  void rotate(int type, int dir = 1) {
    const int *v = f[type];
    int a, b, c, t;
    a = v[0];
    b = v[1];
    c = v[2];
    t = id[type];
    if (dir < 0)
      swap(a, c);
    id[type] = id[a];
    id[a] = id[b];
    id[b] = id[c];
    id[c] = t;
  }

  bool next() {
    ++cnt;
    if (cnt == 24) {
      rotate(0, -1);
      rotate(1, -1);
      cnt = 0;
      return false;
    }
    if (cnt == 4 * 3) {
      rotate(2, -1);
      rotate(0, -1);
    } else if (cnt % 4 == 0) {
      rotate(2);
    } else {
      rotate(0);
    }
    return true;
  }

  void roll(int dir) {
    // const static int dx[] = {1,0,-1,0};
    // const static int dy[] = {0,1,0,-1};
    switch (dir) {
    case 0:
      rotate(1, -1);
      break;
    case 1:
      rotate(2, 1);
      break;
    case 2:
      rotate(1, 1);
      break;
    case 3:
      rotate(2, -1);
      break;
    }
  }

  bool operator<(const Dice &d) const {
    for (int i = 0; i < 3; ++i)
      if (id[i] != d.id[i])
        return id[i] < d.id[i];
    return false;
  }

  void show() {
    cout << id[4] << " / \\\\ " << id[5] << endl;
    cout << " /   \\\\" << endl;
    cout << "|\\\\ " << id[2] << " /|" << endl;
    cout << "|" << id[0] << "\\\\ /" << id[1] << "|" << endl;
    cout << " \\\\ | /" << endl;
    cout << "  \\\\|/" << endl;
    cout << "   " << id[3] << endl;
  }
};
const int Dice::f[3][3] = {{4, 5, 1}, {3, 4, 2}, {5, 3, 0}};

vector<string> F;
vector<int> used;
int S[2][2][2];
vector<Dice> ds;
int G[2][2][2];

inline bool equals(char a, char b) {
  if (a > b)
    swap(a, b);
  return b - a == 'a' - 'A';
}

bool rec(int pos) {
  const static int X[8] = {0, 1, 0, 0, 1, 1, 0, 1};
  const static int Y[8] = {0, 0, 1, 0, 1, 0, 1, 1};
  const static int Z[8] = {0, 0, 0, 1, 0, 1, 1, 1};
  const static int size[8] = {0, 1, 1, 1, 2, 2, 2, 3};
  const static int dx[8][3] = {{-1, -1, -1}, {0, -1, -1}, {0, -1, -1},
                               {0, -1, -1},  {1, 0, -1},  {1, 0, -1},
                               {0, 0, -1},   {1, 1, 0}};
  const static int dy[8][3] = {{-1, -1, -1}, {0, -1, -1}, {0, -1, -1},
                               {0, -1, -1},  {0, 1, -1},  {0, 0, -1},
                               {1, 0, -1},   {1, 0, 1}};
  const static int dz[8][3] = {{-1, -1, -1}, {0, -1, -1}, {0, -1, -1},
                               {0, -1, -1},  {0, 0, -1},  {0, 1, -1},
                               {0, 1, -1},   {0, 1, 1}};
  const static int p[8][3] = {{-1, -1, -1}, {4, -1, -1}, {5, -1, -1},
                              {3, -1, -1},  {5, 4, -1},  {3, 4, -1},
                              {3, 5, -1},   {3, 5, 4}};
  if (pos == 8)
    return true;
  const int &x = X[pos];
  const int &y = Y[pos];
  const int &z = Z[pos];
  // cout << x << ", " << y << ", " << z << endl;
  for (int i = 0; i < 8; ++i) {
    if (used[i])
      continue;
    if (pos == 0 && i != 0)
      return false;
    S[x][y][z] = i;
    used[i] = true;
    for (int j = 0; j < ds.size(); ++j) {
      try {
        const Dice &d = ds[j];
        for (int k = 0; k < size[pos]; ++k) {
          const int &t = S[dx[pos][k]][dy[pos][k]][dz[pos][k]];
          const Dice &e = ds[G[dx[pos][k]][dy[pos][k]][dz[pos][k]]];
          if (!equals(F[i][d.id[p[pos][k]]], F[t][e.id[5 - p[pos][k]]]))
            throw 0;
        }
        G[x][y][z] = j;
        if (rec(pos + 1))
          return true;
      } catch (...) {
      }
    }
    used[i] = false;
  }
  return false;
}

int main() {
  {
    Dice d;
    do {
      ds.push_back(d);
    } while (d.next());
  }
  F = vector<string>(8, string(6, ' '));
  map<char, int> m;
  while (1) {
    for (int i = 0; i < 8; ++i) {
      string s;
      cin >> s;
      if (s == "0")
        return 0;
      F[i][2] = s[0];
      F[i][0] = s[1];
      F[i][1] = s[2];
      F[i][4] = s[3];
      F[i][5] = s[4];
      F[i][3] = s[5];
      for (int j = 0; j < 6; ++j) {
        m[F[i][j]] += 1;
      }
    }
    int cnt = 0;
    for (map<char, int>::iterator it = m.begin(); it != m.end(); ++it) {
      if (isupper(it->first)) {
        cnt += min(it->second, m[tolower(it->first)]);
      }
    }
    if (cnt < 12) {
      cout << "NO" << endl;
      continue;
    }
    used = vector<int>(8, 0);
    fill(G[0][0], G[2][0], -1);
    fill(S[0][0], S[2][0], -1);
    if (rec(0))
      cout << "YES" << endl;
    else
      cout << "NO" << endl;
  }
  return 0;
}