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

#include <cctype>
#include <cstdio>
#include <cstring>
#include <vector>
using namespace std;

enum FACE { TOP, BOTTOM, FRONT, BACK, LEFT, RIGHT };
class Dice {
public:
  Dice() {}

  Dice(char m[7]) {
    f[TOP] = 0;
    f[FRONT] = 1;
    f[LEFT] = 2;
    f[RIGHT] = 3;
    f[BACK] = 4;
    f[BOTTOM] = 5;

    memcpy(val, m, sizeof(val));
  }
  void rotate(FACE a, FACE b, FACE c, FACE d) {
    int tmp = f[a];
    f[a] = f[b];
    f[b] = f[c];
    f[c] = f[d];
    f[d] = tmp;
  }

  vector<Dice> all_rotate() {
    vector<Dice> t;
    for (int i = 0; i < 6; (i & 1 ? rotateY() : rotateX()), i++)
      for (int j = 0; j < 4; rotateZ(), j++)
        t.push_back(*this);

    return t;
  }

  void rotateX() { rotate(TOP, BACK, BOTTOM, FRONT); }
  void rotateY() { rotate(TOP, LEFT, BOTTOM, RIGHT); }
  void rotateZ() { rotate(FRONT, RIGHT, BACK, LEFT); }
  char GetVal(FACE fe) { return val[f[fe]]; }

  int f[6];
  char val[7];
};

Dice pz[2][2][2];
bool fl[2][2][2];
int num[2][2][2];

bool eq[8][8];
bool used[8];
vector<vector<Dice>> all_face;

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

int nx[] = {0, 0, 1, 1, 0, 0, 1, 1};
int ny[] = {0, 1, 0, 1, 0, 1, 0, 1};
int nz[] = {0, 0, 0, 0, 1, 1, 1, 1};

FACE chk1[] = {LEFT, BACK, RIGHT, FRONT, TOP, BOTTOM};
FACE chk2[] = {RIGHT, FRONT, LEFT, BACK, BOTTOM, TOP};

bool isequal(char l, char r) {
  if (isupper(l) && isupper(r))
    return false;
  if (islower(l) && islower(r))
    return false;

  if (isupper(l))
    return tolower(l) == r;

  return toupper(l) == r;
}

bool dfs(int x, int y, int z, int p) {
  if (p == 8)
    return true;
  int l = (p == 0 ? 1 : 8);
  for (int i = 0; i < l; i++) {
    int fcnt = 0;
    if (used[i])
      continue;
    for (int j = 0; j < 24; j++) {
      int cnt = 0;
      bool g = true, ct = false;
      pz[x][y][z] = all_face[i][j];
      for (int k = 0; k < 6; k++) {

        int tx = x + dx[k], ty = y + dy[k], tz = z + dz[k];
        if (tx < 0 || ty < 0 || tz < 0 || tx >= 2 || ty >= 2 || tz >= 2)
          continue;
        if (!fl[tx][ty][tz])
          continue;

        cnt++;
        int dn = num[tx][ty][tz];
        if (!eq[i][dn]) {
          ct = true;
          break;
        }
        if (!isequal(pz[x][y][z].GetVal(chk1[k]),
                     pz[tx][ty][tz].GetVal(chk2[k]))) {
          g = false;
          break;
        }
      }

      if (ct)
        break;
      if (!g)
        continue;
      fcnt++;

      num[x][y][z] = i;
      fl[x][y][z] = 1;
      used[i] = 1;

      if (dfs(nx[p + 1], ny[p + 1], nz[p + 1], p + 1))
        return true;

      num[x][y][z] = -1;
      fl[x][y][z] = 0;
      used[i] = 0;

      if (cnt >= 2)
        break;
      if (cnt == 1 && fcnt >= 4)
        break;
    }
  }

  return false;
}

int main() {
  char b[7];
  while (scanf("%s", b), b[0] != '0') {
    memset(fl, 0, sizeof(fl));
    memset(eq, 0, sizeof(eq));
    memset(used, 0, sizeof(used));
    all_face.clear();
    for (int i = 0; i < 8; i++) {
      Dice d(b);
      all_face.push_back(d.all_rotate());
      if (i == 7)
        break;
      scanf("%s", b);
    }

    for (int i = 0; i < 8; i++)
      for (int j = i + 1; j < 8; j++) {
        if (i == j)
          continue;
        for (int k = 0; k < 6; k++)
          for (int l = 0; l < 6; l++) {
            if (isequal(all_face[i][0].val[k], all_face[j][0].val[l])) {
              eq[i][j] = 1;
              eq[j][i] = 1;
            }
          }
      }

    if (dfs(nx[0], ny[0], nz[0], 0))
      puts("YES");
    else
      puts("NO");
  }
}

Error: TLE

Fixed submission:

#include <cctype>
#include <cstdio>
#include <cstring>
#include <vector>
using namespace std;

enum FACE { TOP, BOTTOM, FRONT, BACK, LEFT, RIGHT };
class Dice {
public:
  Dice() {}

  Dice(char m[7]) {
    f[TOP] = 0;
    f[FRONT] = 1;
    f[LEFT] = 2;
    f[RIGHT] = 3;
    f[BACK] = 4;
    f[BOTTOM] = 5;

    memcpy(val, m, sizeof(val));
  }
  void rotate(FACE a, FACE b, FACE c, FACE d) {
    int tmp = f[a];
    f[a] = f[b];
    f[b] = f[c];
    f[d] = tmp;
  }

  void all_rotate(vector<Dice> &t) {
    for (int i = 0; i < 6; (i & 1 ? rotateY() : rotateX()), i++)
      for (int j = 0; j < 4; rotateZ(), j++) {
        t.push_back(*this);
      }
  }

  void rotateX() { rotate(TOP, BACK, BOTTOM, FRONT); }
  void rotateY() { rotate(TOP, LEFT, BOTTOM, RIGHT); }
  void rotateZ() { rotate(FRONT, RIGHT, BACK, LEFT); }
  char GetVal(FACE fe) { return val[f[fe]]; }

  int f[6];
  char val[7];
};

Dice pz[2][2][2];
bool fl[2][2][2];
int num[2][2][2];

bool eq[8][8];
bool used[8];
vector<vector<Dice>> all_face;

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

int nx[] = {0, 0, 1, 1, 0, 1, 1, 0};
int ny[] = {0, 1, 0, 1, 0, 1, 0, 1};
int nz[] = {0, 0, 0, 0, 1, 1, 1, 1};

FACE chk1[] = {LEFT, BACK, RIGHT, FRONT, TOP, BOTTOM};
FACE chk2[] = {RIGHT, FRONT, LEFT, BACK, BOTTOM, TOP};

bool isequal(char l, char r) {
  if (isupper(l) && isupper(r))
    return false;
  if (islower(l) && islower(r))
    return false;

  if (isupper(l)) {
    return tolower(l) == r;
  }

  return toupper(l) == r;
}

bool dfs(int x, int y, int z, int p) {
  if (p == 8)
    return true;

  for (int i = 0; i < 8; i++) {
    int tcnt = 0;
    if (used[i])
      continue;
    for (int j = 0; j < 24; j++) {
      int cnt = 0;
      bool g = true, ct = false;
      pz[x][y][z] = all_face[i][j];
      for (int k = 0; k < 6; k++) {
        int tx = x + dx[k], ty = y + dy[k], tz = z + dz[k];
        if (tx < 0 || ty < 0 || tz < 0 || tx >= 2 || ty >= 2 || tz >= 2)
          continue;
        if (!fl[tx][ty][tz])
          continue;

        int dn1 = i, dn2 = num[tx][ty][tz];
        if (!eq[dn1][dn2]) {
          ct = true;
          break;
        }

        cnt++;
        if (!isequal(pz[x][y][z].GetVal(chk1[k]),
                     pz[tx][ty][tz].GetVal(chk2[k]))) {
          g = false;
          break;
        }
      }
      if (ct)
        break;
      if (!g)
        continue;
      tcnt++;

      num[x][y][z] = i;
      fl[x][y][z] = 1;
      used[i] = 1;

      if (dfs(nx[p + 1], ny[p + 1], nz[p + 1], p + 1))
        return true;

      fl[x][y][z] = 0;
      used[i] = 0;
      num[x][y][z] = -1;

      if (cnt >= 2)
        break;
      if (cnt == 1 && tcnt >= 4)
        break;
    }
  }

  return false;
}

int main() {
  char b[7];
  while (scanf("%s", b), b[0] != '0') {
    memset(fl, 0, sizeof(fl));
    memset(eq, 0, sizeof(eq));
    memset(used, 0, sizeof(used));
    vector<Dice> dice;
    all_face.clear();
    for (int i = 0; i < 8; i++) {
      Dice d(b);
      dice.push_back(d);
      vector<Dice> t;
      d.all_rotate(t);
      all_face.push_back(t);
      if (i == 7)
        break;
      scanf("%s", b);
    }

    for (int i = 0; i < 8; i++)
      for (int j = i + 1; j < 8; j++) {
        if (i == j)
          continue;
        for (int k = 0; k < 6; k++)
          for (int l = 0; l < 6; l++) {
            if (isequal(dice[i].val[k], dice[j].val[l])) {
              eq[i][j] = 1;
              eq[j][i] = 1;
            }
          }
      }

    if (dfs(nx[0], ny[0], nz[0], 0))
      puts("YES");
    else
      puts("NO");
  }
}