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

#include <algorithm>
#include <cassert>
#include <cmath>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <iostream>
#include <map>
#include <queue>
#include <set>
#include <sstream>
#include <stack>
#include <string>
#include <vector>

using namespace std;

#define FOR(i, k, n) for (int i = (k); i < (int)(n); ++i)
#define REP(i, n) FOR(i, 0, n)
#define FORIT(i, c)                                                            \\
  for (__typeof((c).begin()) i = (c).begin(); i != (c).end(); ++i)

template <class T> void debug(T begin, T end) {
  for (T i = begin; i != end; ++i)
    cerr << *i << " ";
  cerr << endl;
}
inline bool valid(int x, int y, int W, int H) {
  return (x >= 0 && y >= 0 && x < W && y < H);
}

typedef long long ll;
const int INF = 100000000;
const double EPS = 1e-8;
const int MOD = 1000000007;
int dx[8] = {1, 0, -1, 0, 1, -1, -1, 1};
int dy[8] = {0, 1, 0, -1, 1, 1, -1, -1};
enum FACE { FRONT, RIGHT, TOP, BOTTOM, LEFT, BACK };
void roll(int v[6], int a, int b, int c, int d) {
  int tmp = v[a];
  v[a] = v[b];
  v[b] = v[c];
  v[c] = v[d];
  v[d] = tmp;
}
void roll_x(int v[6]) { roll(v, TOP, BACK, BOTTOM, FRONT); }
void roll_y(int v[6]) { roll(v, TOP, LEFT, BOTTOM, RIGHT); }
void roll_z(int v[6]) { roll(v, FRONT, RIGHT, BACK, LEFT); }
int N;
int dice[4][6];
string dice_str[4][6];
int min_ans;
void dfs(int k) {
  if (k == N) {
    int res = 0;
    for (int i = 0; i < 6; i++) {
      int cnt[100] = {};
      int max_c = 0;
      for (int j = 0; j < N; j++) {
        cnt[dice[j][i]]++;
        max_c = max(max_c, cnt[dice[j][i]]);
      }
      res += N - max_c;
      if (res >= min_ans)
        return;
    }
    min_ans = res;
  } else {
    for (int i = 0; i < 6; (i & 1 ? roll_x(dice[k]) : roll_y(dice[k])), ++i) {
      for (int j = 0; j < 4; roll_z(dice[k]), ++j) {
        dfs(k + 1);
      }
    }
  }
}
struct ID {
  map<string, int> provider;
  int get(string s) {
    if (provider.count(s))
      return provider[s];
    int t = provider.size();
    return provider[s] = t;
  }
};

int main() {
  while (cin >> N && N) {
    REP(i, N) REP(j, 6) cin >> dice_str[i][j];
    ID id;
    REP(i, N) REP(j, 6) { dice[i][j] = id.get(dice_str[i][j]); }
    min_ans = INF;
    dfs(0);
    cout << min_ans << endl;
  }
  return 0;
}

Error: TLE

Fixed submission:

#include <algorithm>
#include <cassert>
#include <cmath>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <iostream>
#include <map>
#include <queue>
#include <set>
#include <sstream>
#include <stack>
#include <string>
#include <vector>

using namespace std;

#define FOR(i, k, n) for (int i = (k); i < (int)(n); ++i)
#define REP(i, n) FOR(i, 0, n)
#define FORIT(i, c)                                                            \\
  for (__typeof((c).begin()) i = (c).begin(); i != (c).end(); ++i)

template <class T> void debug(T begin, T end) {
  for (T i = begin; i != end; ++i)
    cerr << *i << " ";
  cerr << endl;
}
inline bool valid(int x, int y, int W, int H) {
  return (x >= 0 && y >= 0 && x < W && y < H);
}

typedef long long ll;
const int INF = 100000000;
const double EPS = 1e-8;
const int MOD = 1000000007;
int dx[8] = {1, 0, -1, 0, 1, -1, -1, 1};
int dy[8] = {0, 1, 0, -1, 1, 1, -1, -1};
enum FACE { FRONT, RIGHT, TOP, BOTTOM, LEFT, BACK };
void roll(string v[6], int a, int b, int c, int d) {
  string tmp = v[a];
  v[a] = v[b];
  v[b] = v[c];
  v[c] = v[d];
  v[d] = tmp;
}
void roll_x(string v[6]) { roll(v, TOP, BACK, BOTTOM, FRONT); }
void roll_y(string v[6]) { roll(v, TOP, LEFT, BOTTOM, RIGHT); }
void roll_z(string v[6]) { roll(v, FRONT, RIGHT, BACK, LEFT); }
int N;
string dice[4][6];
int min_ans;
void dfs(int k) {
  if (k == N) {
    int res = 0;
    for (int i = 0; i < 6; i++) {
      map<string, int> cnt;
      int max_c = 0;
      for (int j = 0; j < N; j++) {
        cnt[dice[j][i]]++;
        max_c = max(max_c, cnt[dice[j][i]]);
      }
      res += N - max_c;
      if (res >= min_ans)
        return;
    }
    min_ans = res;
  } else {
    for (int i = 0; i < 6; (i & 1 ? roll_x(dice[k]) : roll_y(dice[k])), ++i) {
      for (int j = 0; j < 4; roll_z(dice[k]), ++j) {
        dfs(k + 1);
      }
    }
  }
}

int main() {
  while (cin >> N && N) {
    REP(i, N) REP(j, 6) cin >> dice[i][j];
    min_ans = INF;
    dfs(0);
    cout << min_ans << endl;
  }
  return 0;
}