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

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

enum { TOP = 0, FRONT, RIGHT, LEFT, BACK, BOTTOM };
#define rep(i, n) for (int i = 0; i < (int)(n); ++i)
#define rotate_swap(x, a, b, c, d)                                             \\
  swap(x.m[a], x.m[b]);                                                        \\
  swap(x.m[b], x.m[c]);                                                        \\
  swap(x.m[c], x.m[d]);

class Dice {
public:
  int m[6];
  bool operator<(const Dice &a) const {
    rep(i, 6) if (m[i] != a.m[i]) return m[i] < a.m[i];
    return false;
  }
};

void rotate_r(Dice &x) { rotate_swap(x, TOP, LEFT, BOTTOM, RIGHT); }
void rotate_f(Dice &x) { rotate_swap(x, TOP, BACK, BOTTOM, FRONT); }
void rotate_cw(Dice &x) { rotate_swap(x, BACK, LEFT, FRONT, RIGHT); }

Dice ds[4];
Dice data[4][24];

void generate_all(int id, Dice x) {
  rep(i, 6) {
    rep(j, 4) {
      data[id][i * 4 + j] = x;
      rotate_cw(x);
    }

    if (i % 2 == 0)
      rotate_r(x);
    else
      rotate_f(x);
  }
}

int main() {
  int n;
  while (cin >> n && n) {
    int id = 0;
    map<string, int> D;
    for (int i = 0; i < n; ++i) {
      for (int j = 0; j < 6; ++j) {
        string color;
        cin >> color;
        if (D.find(color) == D.end()) {
          D[color] = id++;
        }
        ds[i].m[j] = D[color];
        // cout << ds[i].m[j] << ' ';
      }
      // cout << endl;
      generate_all(i, ds[i]);
    }
    // cout <<"input end" << endl;

    int res = 1000;
    map<int, int> M;
    for (int a = 0; a < 24; ++a) {
      for (int b = 0; b < (n >= 2 ? 24 : 1); ++b) {
        for (int c = 0; c < (n >= 3 ? 24 : 1); ++c) {
          for (int d = 0; d < (n >= 4 ? 24 : 1); ++d) {
            int cost = 0;
            for (int k = 0; k < 6; ++k) {
              int cs[24] = {
                  0,
              };
              int sz = 0;
              if (n >= 1)
                cs[data[0][a].m[k]]++;
              if (n >= 2)
                cs[data[1][b].m[k]]++;
              if (n >= 3)
                cs[data[2][c].m[k]]++;
              if (n >= 4)
                cs[data[3][d].m[k]]++;

              for (int l = 0; l < 24; ++l)
                sz += cs[l] != 0 ? 1 : 0;

              if (sz == 4) {
                cost += 3;
              } else if (sz == 3) {
                cost += 2;
              } else if (sz == 2) {
                if (n == 2) {
                  cost += 1;
                } else {
                  for (int l = 0; l < 24; ++l) {
                    if (cs[l] != 0) {
                      if ((n == 4 && (cs[l] == 3 || cs[l] == 1)) || n == 3) {
                        cost += 1;
                        break;
                      } else if (n == 4 && cs[l] == 2) {
                        cost += 2;
                        break;
                      }
                    }
                  }
                }
              } else if (sz == 1)
                continue;
              if (cost >= res)
                break;
            }
            // cout << a << ' ' << b << ' ' << c << ' ' << d << ' ' << cost <<
            // endl;
            res = min(res, cost);
          }
        }
      }
    }
    cout << res << endl;
  }
  return 0;
}

Error: TLE

Fixed submission:

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

enum { TOP = 0, FRONT, RIGHT, LEFT, BACK, BOTTOM };
#define rep(i, n) for (int i = 0; i < (int)(n); ++i)
#define rotate_swap(x, a, b, c, d)                                             \\
  swap(x.m[a], x.m[b]);                                                        \\
  swap(x.m[b], x.m[c]);                                                        \\
  swap(x.m[c], x.m[d]);

class Dice {
public:
  int m[6];
  bool operator<(const Dice &a) const {
    rep(i, 6) if (m[i] != a.m[i]) return m[i] < a.m[i];
    return false;
  }
};

void rotate_r(Dice &x) { rotate_swap(x, TOP, LEFT, BOTTOM, RIGHT); }
void rotate_f(Dice &x) { rotate_swap(x, TOP, BACK, BOTTOM, FRONT); }
void rotate_cw(Dice &x) { rotate_swap(x, BACK, LEFT, FRONT, RIGHT); }

Dice ds[4];
Dice data[4][24];

void generate_all(int id, Dice x) {
  rep(i, 6) {
    rep(j, 4) {
      data[id][i * 4 + j] = x;
      rotate_cw(x);
    }

    if (i % 2 == 0)
      rotate_r(x);
    else
      rotate_f(x);
  }
}

int main() {
  int n;
  while (cin >> n && n) {
    int id = 0;
    map<string, int> D;
    for (int i = 0; i < n; ++i) {
      for (int j = 0; j < 6; ++j) {
        string color;
        cin >> color;
        if (D.find(color) == D.end()) {
          D[color] = id++;
        }
        ds[i].m[j] = D[color];
        // cout << ds[i].m[j] << ' ';
      }
      // cout << endl;
      generate_all(i, ds[i]);
    }
    // cout <<"input end" << endl;

    int res = 1000;
    for (int a = 0; a < 24; ++a) {
      for (int b = 0; b < (n >= 2 ? 24 : 1); ++b) {
        for (int c = 0; c < (n >= 3 ? 24 : 1); ++c) {
          for (int d = 0; d < (n >= 4 ? 24 : 1); ++d) {
            int cost = 0;
            for (int k = 0; k < 6; ++k) {
              map<int, int> M;
              if (n >= 1) {
                M[data[0][a].m[k]]++;
              }
              if (n >= 2) {
                M[data[1][b].m[k]]++;
              }
              if (n >= 3) {
                M[data[2][c].m[k]]++;
              }
              if (n >= 4) {
                M[data[3][d].m[k]]++;
              }
              // cout << data[0][a].m[k] << ' ' << data[1][b].m[k] << ' ' <<
              // data[2][c].m[k] << endl;

              int sz = M.size();
              // cout << sz << endl;
              if (sz == 4) {
                cost += 3;
              } else if (sz == 3) {
                cost += 2;
              } else if (sz == 2) {
                if (n == 2) {
                  cost += 1;
                } else {
                  for (map<int, int>::iterator it = M.begin(); it != M.end();
                       ++it) {
                    if ((n == 4 && (it->second == 3 || it->second == 1)) ||
                        n == 3) {
                      cost += 1;
                      break;
                    } else if (n == 4 && it->second == 2) {
                      cost += 2;
                      break;
                    }
                  }
                }
              } else if (sz == 1)
                continue;
              if (cost >= res)
                break;
            }
            // cout << a << ' ' << b << ' ' << c << ' ' << d << ' ' << cost <<
            // endl;
            res = min(res, cost);
          }
        }
      }
    }
    cout << res << endl;
  }
  return 0;
}