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

#include <algorithm>
#include <climits>
#include <cmath>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <functional>
#include <iostream>
#include <map>
#include <numeric>
#include <queue>
#include <set>
#include <sstream>
#include <stack>
#include <string>
#include <vector>
using namespace std;

typedef istringstream ISS;
typedef ostringstream OSS;
typedef vector<string> VS;
typedef int INT;
typedef vector<INT> VI;
typedef vector<VI> VVI;
typedef pair<INT, INT> II;
typedef vector<II> VII;

template <class T> ostream &operator<<(ostream &os, vector<T> v) {
  for (typename vector<T>::iterator it_i = v.begin(); it_i != v.end(); ++it_i) {
    os << *it_i << ", ";
  }
  return os;
}

VS R(8);
VS L(8);
bool used[8];

char DI[24][6] = {{0, 1, 2, 3, 4, 5}, {0, 2, 4, 1, 3, 5}, {0, 3, 1, 4, 2, 5},
                  {0, 4, 3, 2, 1, 5}, {1, 0, 3, 2, 5, 4}, {1, 2, 0, 5, 3, 4},
                  {1, 3, 5, 0, 2, 4}, {1, 5, 2, 3, 0, 4}, {2, 0, 1, 4, 5, 3},
                  {2, 1, 5, 0, 4, 3}, {2, 4, 0, 5, 1, 3}, {2, 5, 4, 1, 0, 3},
                  {3, 0, 4, 1, 5, 2}, {3, 1, 0, 5, 4, 2}, {3, 4, 5, 0, 1, 2},
                  {3, 5, 1, 4, 0, 2}, {4, 0, 2, 3, 5, 1}, {4, 2, 5, 0, 3, 1},
                  {4, 3, 0, 5, 2, 1}, {4, 5, 3, 2, 0, 1}, {5, 1, 3, 2, 4, 0},
                  {5, 2, 1, 4, 3, 0}, {5, 3, 4, 1, 2, 0}, {5, 4, 2, 3, 1, 0}};
int CI[8][8] = {
    {-1},       {0, 3, -1},       {1, 1, -1},       {0, 1, 2, 2, -1},
    {0, 5, -1}, {1, 5, 4, 3, -1}, {2, 5, 5, 1, -1}, {3, 5, 4, 1, 6, 2, -1}};

string DiceRot(string s, int t) {
  string res = s;
  for (int i = 0; i < 6; ++i) {
    res[DI[t][i]] = s[i];
  }
  return res;
}

bool check(char a, char b) { return (a != b) && (tolower(a) == tolower(b)); }

bool dfs(int depth) {
  if (depth == 0) {
    for (int u = 0; u < 8; ++u) {
      if (used[u])
        continue;
      used[u] = true;
      for (int i = 0; i < 24; ++i) {
        R[1] = DiceRot(L[u], i);
        if (dfs(depth + 1))
          return true;
      }
      used[u] = false;
    }
  } else if (depth == 1) {
    for (int u = 0; u < 8; ++u) {
      if (used[u])
        continue;
      used[u] = true;
      for (int i = 0; i < 24; ++i) {
        R[2] = DiceRot(L[u], i);
        if (check(R[2][3], R[0][2]) && check(R[2][5], R[1][0])) {
          if (dfs(depth + 1))
            return true;
        }
      }
      used[u] = false;
    }
  } else if (depth == 2) {
    for (int u = 0; u < 8; ++u) {
      if (used[u])
        continue;
      used[u] = true;
      for (int i = 0; i < 24; ++i) {
        R[3] = DiceRot(L[u], i);
        if (check(R[3][0], R[0][5]) && check(R[3][2], R[1][3])) {
          if (dfs(depth + 1))
            return true;
        }
      }
      used[u] = false;
    }
  } else if (depth == 3) {
    for (int u = 0; u < 8; ++u) {
      if (used[u])
        continue;
      used[u] = true;
      for (int i = 0; i < 24; ++i) {
        R[4] = DiceRot(L[u], i);
        if (check(R[4][1], R[0][4])) {
          if (dfs(depth + 1))
            return true;
        }
      }
      used[u] = false;
    }
  } else if (depth == 4) {
    for (int u = 0; u < 8; ++u) {
      if (used[u])
        continue;
      used[u] = true;
      for (int i = 0; i < 24; ++i) {
        R[5] = DiceRot(L[u], i);
        if (check(R[5][1], R[1][4])) {
          if (dfs(depth + 1))
            return true;
        }
      }
      used[u] = false;
    }
  } else if (depth == 5) {
    for (int u = 0; u < 8; ++u) {
      if (used[u])
        continue;
      used[u] = true;
      for (int i = 0; i < 24; ++i) {
        R[6] = DiceRot(L[u], i);
        if (check(R[6][1], R[2][4]) && check(R[6][3], R[4][2]) &&
            check(R[6][5], R[5][0])) {
          if (dfs(depth + 1))
            return true;
        }
      }
      used[u] = false;
    }
  } else if (depth == 6) {
    for (int u = 0; u < 8; ++u) {
      if (used[u])
        continue;
      used[u] = true;
      for (int i = 0; i < 24; ++i) {
        R[7] = DiceRot(L[u], i);
        if (check(R[7][1], R[3][4]) && check(R[7][2], R[5][3]) &&
            check(R[7][0], R[4][5])) {
          return true;
        }
        R[7] = "";
      }
      used[u] = false;
    }
  }
  return false;
}

bool solve(int depth) {
  if (depth == 8) {
    return true;
  }
  for (int u = 0; u < 8; ++u) {
    if (used[u])
      continue;
    used[u] = true;
    for (int i = 0; i < 24; ++i) {
      for (int j = 0; j < 6; ++j) {
        R[depth][j] = L[u][DI[i][j]];
      }
      bool flag = true;
      for (int j = 0; CI[depth][j] != -1; j += 2) {
        int p = CI[depth][j];
        int f = CI[depth][j + 1];
        flag &= check(R[p][5 - f], R[depth][f]);
      }
      if (flag)
        if (solve(depth + 1))
          return true;
    }
    used[u] = false;
  }
  return false;
}

int main() {
  string line;
  while (cin >> line) {
    if (line == "0")
      break;
    L[0] = line;
    for (int i = 1; i < 8; ++i)
      cin >> L[i];
    fill(used, used + 8, false);
    R = VS(8, string(6, ' '));
    cout << (solve(0) ? "YES" : "NO") << endl;
  }
  return 0;
}

Error: TLE

Fixed submission:

#include <algorithm>
#include <climits>
#include <cmath>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <functional>
#include <iostream>
#include <map>
#include <numeric>
#include <queue>
#include <set>
#include <sstream>
#include <stack>
#include <string>
#include <vector>
using namespace std;

typedef istringstream ISS;
typedef ostringstream OSS;
typedef vector<string> VS;
typedef int INT;
typedef vector<INT> VI;
typedef vector<VI> VVI;
typedef pair<INT, INT> II;
typedef vector<II> VII;

template <class T> ostream &operator<<(ostream &os, vector<T> v) {
  for (typename vector<T>::iterator it_i = v.begin(); it_i != v.end(); ++it_i) {
    os << *it_i << ", ";
  }
  return os;
}

VS R(8);
VS L(8);
bool used[8];

const int DI[24][6] = {
    {0, 1, 2, 3, 4, 5}, {0, 2, 4, 1, 3, 5}, {0, 3, 1, 4, 2, 5},
    {0, 4, 3, 2, 1, 5}, {1, 0, 3, 2, 5, 4}, {1, 2, 0, 5, 3, 4},
    {1, 3, 5, 0, 2, 4}, {1, 5, 2, 3, 0, 4}, {2, 0, 1, 4, 5, 3},
    {2, 1, 5, 0, 4, 3}, {2, 4, 0, 5, 1, 3}, {2, 5, 4, 1, 0, 3},
    {3, 0, 4, 1, 5, 2}, {3, 1, 0, 5, 4, 2}, {3, 4, 5, 0, 1, 2},
    {3, 5, 1, 4, 0, 2}, {4, 0, 2, 3, 5, 1}, {4, 2, 5, 0, 3, 1},
    {4, 3, 0, 5, 2, 1}, {4, 5, 3, 2, 0, 1}, {5, 1, 3, 2, 4, 0},
    {5, 2, 1, 4, 3, 0}, {5, 3, 4, 1, 2, 0}, {5, 4, 2, 3, 1, 0}};
const int CI[8][8] = {
    {-1},       {0, 3, -1},       {1, 1, -1},       {0, 1, 2, 2, -1},
    {0, 5, -1}, {1, 5, 4, 3, -1}, {2, 5, 5, 1, -1}, {3, 5, 4, 1, 6, 2, -1}};

string DiceRot(string s, int t) {
  string res = s;
  for (int i = 0; i < 6; ++i) {
    res[DI[t][i]] = s[i];
  }
  return res;
}

bool check(char a, char b) { return a != b && tolower(a) == tolower(b); }

bool dfs(int depth) {
  if (depth == 0) {
    for (int u = 0; u < 8; ++u) {
      if (used[u])
        continue;
      used[u] = true;
      for (int i = 0; i < 24; ++i) {
        R[1] = DiceRot(L[u], i);
        if (dfs(depth + 1))
          return true;
      }
      used[u] = false;
    }
  } else if (depth == 1) {
    for (int u = 0; u < 8; ++u) {
      if (used[u])
        continue;
      used[u] = true;
      for (int i = 0; i < 24; ++i) {
        R[2] = DiceRot(L[u], i);
        if (check(R[2][3], R[0][2]) && check(R[2][5], R[1][0])) {
          if (dfs(depth + 1))
            return true;
        }
      }
      used[u] = false;
    }
  } else if (depth == 2) {
    for (int u = 0; u < 8; ++u) {
      if (used[u])
        continue;
      used[u] = true;
      for (int i = 0; i < 24; ++i) {
        R[3] = DiceRot(L[u], i);
        if (check(R[3][0], R[0][5]) && check(R[3][2], R[1][3])) {
          if (dfs(depth + 1))
            return true;
        }
      }
      used[u] = false;
    }
  } else if (depth == 3) {
    for (int u = 0; u < 8; ++u) {
      if (used[u])
        continue;
      used[u] = true;
      for (int i = 0; i < 24; ++i) {
        R[4] = DiceRot(L[u], i);
        if (check(R[4][1], R[0][4])) {
          if (dfs(depth + 1))
            return true;
        }
      }
      used[u] = false;
    }
  } else if (depth == 4) {
    for (int u = 0; u < 8; ++u) {
      if (used[u])
        continue;
      used[u] = true;
      for (int i = 0; i < 24; ++i) {
        R[5] = DiceRot(L[u], i);
        if (check(R[5][1], R[1][4])) {
          if (dfs(depth + 1))
            return true;
        }
      }
      used[u] = false;
    }
  } else if (depth == 5) {
    for (int u = 0; u < 8; ++u) {
      if (used[u])
        continue;
      used[u] = true;
      for (int i = 0; i < 24; ++i) {
        R[6] = DiceRot(L[u], i);
        if (check(R[6][1], R[2][4]) && check(R[6][3], R[4][2]) &&
            check(R[6][5], R[5][0])) {
          if (dfs(depth + 1))
            return true;
        }
      }
      used[u] = false;
    }
  } else if (depth == 6) {
    for (int u = 0; u < 8; ++u) {
      if (used[u])
        continue;
      used[u] = true;
      for (int i = 0; i < 24; ++i) {
        R[7] = DiceRot(L[u], i);
        if (check(R[7][1], R[3][4]) && check(R[7][2], R[5][3]) &&
            check(R[7][0], R[4][5])) {
          return true;
        }
        R[7] = "";
      }
      used[u] = false;
    }
  }
  return false;
}

bool solve(int depth) {
  if (depth == 8) {
    return true;
  }
  for (int u = 0; u < 8; ++u) {
    if (used[u])
      continue;
    used[u] = true;
    for (int i = 0; i < 24; ++i) {
      string ss = DiceRot(L[u], i);
      R[depth] = ss;
      bool flag = true;
      for (int j = 0; CI[depth][j] != -1; j += 2) {
        int p = CI[depth][j];
        int f = CI[depth][j + 1];
        flag &= check(R[p][5 - f], R[depth][f]);
      }
      if (flag)
        if (solve(depth + 1))
          return true;
    }
    used[u] = false;
  }
  return false;
}

int main() {
  string line;
  while (cin >> line) {
    if (line == "0")
      break;
    L[0] = line;
    for (int i = 1; i < 8; ++i)
      cin >> L[i];
    fill(used, used + 8, false);
    cout << (solve(0) ? "YES" : "NO") << endl;
  }
  return 0;
}