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

#include <algorithm>
#include <iostream>
#include <string>
#include <vector>
using namespace std;

// s[0] := top,   s[1] := front
// s[2] := right, s[3] := left
// s[4] := back,  s[5] := bottom
enum { TOP, FRONT, RIGHT, LEFT, BACK, BOTTOM };

string list[24] = {"012345", "024135", "031425", "043215", "103254", "120534",
                   "135024", "152304", "201453", "215043", "240513", "254103",
                   "304152", "310542", "345012", "351402", "402351", "425031",
                   "430521", "453201", "513240", "521430", "534120", "542310"};

// cube[0..7] := サイコロの状態 string が返ってくる.(入力)
string cube[8];
// used[i] := cube[i] を使ったかどうか
bool used[8];
// s[k][pos] := 位置 pos のダイスの k 番目の文字が返ってくる.
char s[6][8];
// 解
bool ans;

// c1, c2 が同じアルファベットで片方が小文字, もう片方が大文字なら true を返す.
bool check(char c1, char c2) { return (abs(c1 - c2) == 32); }

// s := いままでの使ったサイコロの状態, pos := 位置(0..7)
void dfs(int pos) {
  if (ans)
    return;
  if (pos == 8) {
    ans = true;
    return;
  }

  for (int i = 0; i < 8; i++) {
    if (!used[i]) {
      for (int j = 0; j < 24; j++) {

        for (int k = 0; k < 6; k++) {
          s[k][pos] = cube[i][list[j][k] - '0'];
        }

        used[i] = true;
        if (pos == 0) {
          dfs(pos + 1);
        } else if (pos == 1) {
          if (check(s[RIGHT][0], s[LEFT][1])) {
            dfs(pos + 1);
          }
        } else if (pos == 2) {
          if (check(s[FRONT][0], s[BACK][2])) {
            dfs(pos + 1);
          }
        } else if (pos == 3) {
          if (check(s[RIGHT][2], s[LEFT][3]) &&
              check(s[FRONT][1], s[BACK][3])) {
            dfs(pos + 1);
          }
        } else if (pos == 4) {
          if (check(s[BOTTOM][0], s[TOP][4])) {
            dfs(pos + 1);
          }
        } else if (pos == 5) {
          if (check(s[BOTTOM][1], s[TOP][5]) &&
              check(s[RIGHT][4], s[LEFT][5])) {
            dfs(pos + 1);
          }
        } else if (pos == 6) {
          if (check(s[BOTTOM][2], s[TOP][6]) &&
              check(s[FRONT][4], s[BACK][6])) {
            dfs(pos + 1);
          }
        } else if (pos == 7) {
          if (check(s[BOTTOM][3], s[TOP][7]) &&
              check(s[FRONT][5], s[BACK][7]) &&
              check(s[RIGHT][6], s[LEFT][7])) {
            dfs(pos + 1);
            return;
          }
        }
        used[i] = false;
      }
    }
  }
}

int main() {
  string s_;
  while (cin >> s_, s_ != "0") {
    // 初期化
    ans = false;
    cube[0] = s_;
    for (int i = 0; i < 8; i++)
      used[i] = false;

    for (int i = 1; i < 8; i++) {
      cin >> cube[i];
    }
    dfs(0);
    cout << (ans ? "YES" : "NO") << endl;
  }
}

Error: TLE

Fixed submission:

#include <algorithm>
#include <iostream>
#include <string>
#include <vector>
using namespace std;

// s[0] := top,   s[1] := front
// s[2] := right, s[3] := left
// s[4] := back,  s[5] := bottom
enum { TOP, FRONT, RIGHT, LEFT, BACK, BOTTOM };

string list[24] = {"012345", "024135", "031425", "043215", "103254", "120534",
                   "135024", "152304", "201453", "215043", "240513", "254103",
                   "304152", "310542", "345012", "351402", "402351", "425031",
                   "430521", "453201", "513240", "521430", "534120", "542310"};

// サイコロの状態24通りのどれかを返す.
string get_dice(const string &s, int k) {
  string result = s;
  for (int i = 0; i < 6; i++) {
    result[i] = s[list[k][i] - '0'];
  }
  return result;
}

// cube[0..7] := サイコロの状態 string が返ってくる.(入力)
string cube[8];
// used[i] := cube[i] を使ったかどうか
bool used[8];
// s[k][pos] := 位置 pos のダイスの k 番目の文字が返ってくる.
char s[6][8];
// 解
bool ans;

// c1, c2 が同じアルファベットで片方が小文字, もう片方が大文字なら true を返す.
bool check(char c1, char c2) { return (abs(c1 - c2) == 32); }

// s := いままでの使ったサイコロの状態, pos := 位置(0..7)
void dfs(int pos) {
  if (ans)
    return;
  if (pos == 8) {
    ans = true;
    return;
  }
  /// cout << "pos:" << pos << endl;

  for (int i = 0; i < 8; i++) {
    if (!used[i]) {
      for (int j = 0; j < 24; j++) {
        string next = get_dice(cube[i], j);
        for (int k = 0; k < 6; k++) {
          s[k][pos] = next[k];
        }
        used[i] = true;
        if (pos == 0) {
          dfs(pos + 1);
        } else if (pos == 1) {
          if (check(s[RIGHT][0], s[LEFT][1])) {
            dfs(pos + 1);
          }
        } else if (pos == 2) {
          if (check(s[FRONT][0], s[BACK][2])) {
            dfs(pos + 1);
          }
        } else if (pos == 3) {
          if (check(s[RIGHT][2], s[LEFT][3]) &&
              check(s[FRONT][1], s[BACK][3])) {
            dfs(pos + 1);
          }
        } else if (pos == 4) {
          if (check(s[BOTTOM][0], s[TOP][4])) {
            dfs(pos + 1);
          }
        } else if (pos == 5) {
          if (check(s[BOTTOM][1], s[TOP][5]) &&
              check(s[RIGHT][4], s[LEFT][5])) {
            dfs(pos + 1);
          }
        } else if (pos == 6) {
          if (check(s[BOTTOM][2], s[TOP][6]) &&
              check(s[FRONT][4], s[BACK][6])) {
            dfs(pos + 1);
          }
        } else if (pos == 7) {
          if (check(s[BOTTOM][3], s[TOP][7]) &&
              check(s[FRONT][5], s[BACK][7]) &&
              check(s[RIGHT][6], s[LEFT][7])) {
            dfs(pos + 1);
            return;
          }
        }
        used[i] = false;
      }
    }
  }
}

int main() {
  string s_;
  while (cin >> s_, s_ != "0") {
    // 初期化
    ans = false;
    cube[0] = s_;
    for (int i = 0; i < 8; i++)
      used[i] = false;

    for (int i = 1; i < 8; i++) {
      cin >> cube[i];
    }
    dfs(0);
    cout << (ans ? "YES" : "NO") << endl;
  }
}