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

#include <algorithm>
#include <cctype>
#include <cmath>
#include <complex>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <ctime>
#include <deque>
#include <iostream>
#include <limits>
#include <list>
#include <map>
#include <numeric>
#include <queue>
#include <set>
#include <sstream>
#include <string>
#include <vector>
using namespace std;
#define REP(i, j) for (int i = 0; i < (int)(j); ++i)
#define FOR(i, j, k) for (int i = (int)(j); i < (int)(k); ++i)
#define SORT(v) sort((v).begin(), (v).end())
#define REVERSE(v) reverse((v).begin(), (v).end())
typedef complex<double> P;
const int N = 8;

int H[6][6] = {{1, 5, 2, 3, 0, 4}, {3, 1, 0, 5, 4, 2}, {2, 1, 5, 0, 4, 3},
               {4, 0, 2, 3, 5, 1}, {0, 2, 4, 1, 3, 5}, {0, 3, 1, 4, 2, 5}};

enum { TOP, FRONT, RIGHT, LEFT, BACK, BOTTOM };
struct Cube {
  vector<char> d, bef;
  Cube(vector<char> v) { d = v; }
  Cube(string &s) {
    d = vector<char>(6);
    REP(i, s.length()) d[i] = s[i];
  }
  Cube() { d = vector<char>(6, '-'); }
  void roll(int dir) {
    bef = d;
    for (int i = 0; i < 6; i++)
      d[i] = bef[H[dir][i]];
  }
  string to_string() {
    stringstream ss;
    REP(i, 6) ss << d[i];
    return ss.str();
  }
};

bool ans = false;
int D[12][4] = {{0, 1, RIGHT, LEFT}, {0, 2, FRONT, BACK}, {0, 4, BOTTOM, TOP},
                {1, 3, FRONT, BACK}, {1, 5, BOTTOM, TOP}, {2, 3, RIGHT, LEFT},
                {2, 6, BOTTOM, TOP}, {3, 7, BOTTOM, TOP}, {4, 5, RIGHT, LEFT},
                {4, 6, FRONT, BACK}, {5, 7, FRONT, BACK}, {6, 7, RIGHT, LEFT}};

bool check(int n, vector<Cube> &v) {
  REP(i, 12) {
    int a = D[i][0], b = D[i][1], da = D[i][2], db = D[i][3];
    if (b != n)
      continue;
    if (toupper(v[a].d[da]) != toupper(v[b].d[db]))
      return false;
    if (v[a].d[da] == v[b].d[db])
      return false;
  }
  return true;
}

void dfs(int n, vector<Cube> &v, Cube cs[N], vector<bool> &used) {
  if (ans)
    return;
  if (n >= N) {
    ans = true;
    return;
  }

  REP(i, N) {
    if (used[i])
      continue;
    used[i] = true;

    Cube c = cs[i];
    v[n] = c;
    if (!ans && check(n, v))
      dfs(n + 1, v, cs, used);
    REP(i, 3) {
      c.roll(4);
      v[n] = c;
      if (!ans && check(n, v))
        dfs(n + 1, v, cs, used);
    }
    c.roll(4);

    c.roll(0);
    v[n] = c;
    if (!ans && check(n, v))
      dfs(n + 1, v, cs, used);
    REP(i, 3) {
      c.roll(4);
      v[n] = c;
      if (!ans && check(n, v))
        dfs(n + 1, v, cs, used);
    }
    c.roll(4);

    c.roll(0);
    v[n] = c;
    if (!ans && check(n, v))
      dfs(n + 1, v, cs, used);
    REP(i, 3) {
      c.roll(4);
      v[n] = c;
      if (!ans && check(n, v))
        dfs(n + 1, v, cs, used);
    }
    c.roll(4);

    c.roll(0);
    v[n] = c;
    if (!ans && check(n, v))
      dfs(n + 1, v, cs, used);
    REP(i, 3) {
      c.roll(4);
      v[n] = c;
      if (!ans && check(n, v))
        dfs(n + 1, v, cs, used);
    }
    c.roll(4);

    c.roll(0);
    c.roll(1);
    v[n] = c;
    if (!ans && check(n, v))
      dfs(n + 1, v, cs, used);
    REP(i, 3) {
      c.roll(4);
      v[n] = c;
      if (!ans && check(n, v))
        dfs(n + 1, v, cs, used);
    }
    c.roll(4);

    c.roll(2);
    c.roll(2);
    v[n] = c;
    if (!ans && check(n, v))
      dfs(n + 1, v, cs, used);
    REP(i, 3) {
      c.roll(4);
      v[n] = c;
      if (!ans && check(n, v))
        dfs(n + 1, v, cs, used);
    }
    c.roll(4);

    v[n] = Cube();
    used[i] = false;
  }
}

int main() {
  string s;
  while (cin >> s && s != "0") {
    Cube cs[N];
    cs[0] = Cube(s);
    FOR(i, 1, N) {
      cin >> s;
      cs[i] = Cube(s);
    }

    ans = false;
    vector<Cube> v(N, Cube());
    vector<bool> used(N, 0);
    dfs(0, v, cs, used);
    cout << (ans ? "YES" : "NO") << endl;
  }
  return 0;
}

Error: TLE

Fixed submission:

#include <algorithm>
#include <cctype>
#include <cmath>
#include <complex>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <ctime>
#include <deque>
#include <iostream>
#include <limits>
#include <list>
#include <map>
#include <numeric>
#include <queue>
#include <set>
#include <sstream>
#include <string>
#include <vector>
using namespace std;
#define REP(i, j) for (int i = 0; i < (int)(j); ++i)
#define FOR(i, j, k) for (int i = (int)(j); i < (int)(k); ++i)
#define SORT(v) sort((v).begin(), (v).end())
#define REVERSE(v) reverse((v).begin(), (v).end())
typedef complex<double> P;
const int N = 8;

int H[6][6] = {{1, 5, 2, 3, 0, 4}, {3, 1, 0, 5, 4, 2}, {2, 1, 5, 0, 4, 3},
               {4, 0, 2, 3, 5, 1}, {0, 2, 4, 1, 3, 5}, {0, 3, 1, 4, 2, 5}};

enum { TOP, FRONT, RIGHT, LEFT, BACK, BOTTOM };
struct Cube {
  vector<char> d;
  Cube(vector<char> v) { d = v; }
  Cube(string &s) {
    d = vector<char>(6);
    REP(i, s.length()) d[i] = s[i];
  }
  Cube() { d = vector<char>(6, '-'); }
  void roll(int dir) {
    vector<char> nx(6);
    for (int i = 0; i < 6; i++)
      nx[i] = d[H[dir][i]];
    d = nx;
  }
  string to_string() {
    stringstream ss;
    REP(i, 6) ss << d[i];
    return ss.str();
  }
};

bool ans = false;
int D[12][4] = {{0, 1, RIGHT, LEFT}, {0, 2, FRONT, BACK}, {0, 4, BOTTOM, TOP},
                {1, 3, FRONT, BACK}, {1, 5, BOTTOM, TOP}, {2, 3, RIGHT, LEFT},
                {2, 6, BOTTOM, TOP}, {3, 7, BOTTOM, TOP}, {4, 5, RIGHT, LEFT},
                {4, 6, FRONT, BACK}, {5, 7, FRONT, BACK}, {6, 7, RIGHT, LEFT}};

bool check(int n, vector<Cube> &v) {
  REP(i, 12) {
    int a = D[i][0], b = D[i][1], da = D[i][2], db = D[i][3];
    if (b != n)
      continue;
    if (toupper(v[a].d[da]) != toupper(v[b].d[db]))
      return false;
    if (v[a].d[da] == v[b].d[db])
      return false;
  }
  return true;
}

void dfs(int n, vector<Cube> &v, Cube cs[N], vector<bool> &used) {
  if (ans)
    return;
  if (n >= N) {
    ans = true;
    return;
  }

  REP(i, N) {
    if (used[i])
      continue;
    used[i] = true;

    Cube c = cs[i];
    v[n] = c;
    if (!ans && check(n, v))
      dfs(n + 1, v, cs, used);
    REP(i, 3) {
      c.roll(4);
      v[n] = c;
      if (!ans && check(n, v))
        dfs(n + 1, v, cs, used);
    }
    c.roll(4);

    c.roll(0);
    v[n] = c;
    if (!ans && check(n, v))
      dfs(n + 1, v, cs, used);
    REP(i, 3) {
      c.roll(4);
      v[n] = c;
      if (!ans && check(n, v))
        dfs(n + 1, v, cs, used);
    }
    c.roll(4);

    c.roll(0);
    v[n] = c;
    if (!ans && check(n, v))
      dfs(n + 1, v, cs, used);
    REP(i, 3) {
      c.roll(4);
      v[n] = c;
      if (!ans && check(n, v))
        dfs(n + 1, v, cs, used);
    }
    c.roll(4);

    c.roll(0);
    v[n] = c;
    if (!ans && check(n, v))
      dfs(n + 1, v, cs, used);
    REP(i, 3) {
      c.roll(4);
      v[n] = c;
      if (!ans && check(n, v))
        dfs(n + 1, v, cs, used);
    }
    c.roll(4);

    c.roll(0);
    c.roll(1);
    v[n] = c;
    if (!ans && check(n, v))
      dfs(n + 1, v, cs, used);
    REP(i, 3) {
      c.roll(4);
      v[n] = c;
      if (!ans && check(n, v))
        dfs(n + 1, v, cs, used);
    }
    c.roll(4);

    c.roll(2);
    c.roll(2);
    v[n] = c;
    if (!ans && check(n, v))
      dfs(n + 1, v, cs, used);
    REP(i, 3) {
      c.roll(4);
      v[n] = c;
      if (!ans && check(n, v))
        dfs(n + 1, v, cs, used);
    }
    c.roll(4);

    v[n] = Cube();
    used[i] = false;
  }
}

int main() {
  string s;
  while (cin >> s && s != "0") {
    Cube cs[N];
    cs[0] = Cube(s);
    FOR(i, 1, N) {
      cin >> s;
      cs[i] = Cube(s);
    }

    ans = false;
    vector<Cube> v(N, Cube());
    vector<bool> used(N, 0);
    dfs(0, v, cs, used);
    cout << (ans ? "YES" : "NO") << endl;
  }
  return 0;
}