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

#include <bits/stdc++.h>
#define REP(i, n) for (int i = 0; i < (int)(n); ++i)

using namespace std;
struct Solver {
  int F[3][3];
  int T[3][3];
  int R[3][3];
  int dice_R[7][7]; // [TOP][FRONT] -> RIGHT

  enum FACE { TOP, BOTTOM, FRONT, BACK, LEFT, RIGHT };

  struct Dice {
    vector<int> val;
    Dice(vector<int> init) : val(init) { assert(val.size() == 6); }
    void roll_x() { roll(TOP, BACK, BOTTOM, FRONT); }
    void roll_y() { roll(TOP, LEFT, BOTTOM, RIGHT); }
    void roll_z() { roll(FRONT, RIGHT, BACK, LEFT); }
    void roll_r(int r) {
      if (r == 0)
        roll(TOP, LEFT, BOTTOM, RIGHT);
      if (r == 1)
        roll(TOP, BACK, BOTTOM, FRONT);
      if (r == 2)
        roll(TOP, RIGHT, BOTTOM, LEFT);
      if (r == 3)
        roll(TOP, FRONT, BOTTOM, BACK);
    }
    void roll(int a, int b, int c, int d) { // a, b, c, d -> b, c, d, a
      int tmp = val[a];
      val[a] = val[b];
      val[b] = val[c];
      val[c] = val[d];
      val[d] = tmp;
    }
  };

  Solver() {
    memset(F, 0, sizeof(F));
    memset(T, 0, sizeof(T));
    memset(R, 0, sizeof(R));

    /* input */
    REP(y, 3) REP(x, 3) cin >> T[y][x];
    REP(y, 3) REP(x, 3) cin >> F[y][x];

    Dice a(vector<int>({1, 6, 2, 5, 4, 3}));
    for (int i = 0; i < 6; i++) {
      for (int j = 0; j < 4; j++) {
        // printf("%d %d -> %d\\n", a.val[TOP], a.val[FRONT], a.val[RIGHT]);
        dice_R[a.val[TOP]][a.val[FRONT]] = a.val[RIGHT];
        a.roll_z();
      }
      if (i & 1)
        a.roll_x();
      else
        a.roll_y();
    }
  }

  set<int> answer;

  void rec_F(int x, int y) {
    // printf("F(%d, %d)\\n", x, y);
    if (y == 3) {
      rec_T(0, 0);
    } else {
      int nx = (x + 1 != 3 ? x + 1 : 0);
      int ny = (x + 1 != 3 ? y : y + 1);
      for (int val = 1; val <= 6; val++) {
        if (F[y][x] != 0 && F[y][x] != val)
          continue;
        bool ok = true;
        for (int z = 0; z < 3; z++) {
          if ((T[z][x] == val) || (7 - T[z][x] == val)) {
            ok = false;
          }
        }
        if (ok) {
          int tmp = F[y][x];
          F[y][x] = val;
          rec_F(nx, ny);
          F[y][x] = tmp;
        }
      }
    }
  }

  void rec_T(int x, int z) {
    if (z == 3) {
      check();
    } else {
      int nx = (x + 1 != 3 ? x + 1 : 0);
      int nz = (x + 1 != 3 ? z : z + 1);
      for (int val = 1; val <= 6; val++) {
        if (T[z][x] != 0 && T[z][x] != val)
          continue;
        bool ok = true;
        for (int y = 0; y < 3; y++) {
          if ((F[y][x] == val) || (7 - F[y][x] == val)) {
            ok = false;
          }
          if (x > 0 &&
              dice_R[val][F[y][x]] != dice_R[T[z][x - 1]][F[y][x - 1]]) {
            ok = false;
          }
        }
        if (ok) {
          int tmp = T[z][x];
          T[z][x] = val;
          rec_T(nx, nz);
          T[z][x] = tmp;
        }
      }
    }
  }

  // void rec_R(int z, int y){
  //     if(y == 3){
  //     }else{
  //         int nz = (z + 1 != 3 ? z + 1 : 0);
  //         int ny = (z + 1 != 3 ? y : y + 1);
  //         assert(R[y][z] == 0);
  //         for(int val = 1; val <= 6; val++){
  //             bool ok = true;
  //             for(int x = 0; x < 3; x++){
  //                 if((F[y][x] == val) || (7 - F[y][x] == val)){
  //                     ok = false;
  //                 }
  //                 if((T[2 - z][x] == val) || (7 - T[2 - z][x] == val)){
  //                     ok = false;
  //                 }
  //             }
  //             if(ok){
  //                 R[y][z] = val;
  //                 rec_R(nz, ny);
  //                 R[y][z] = 0;
  //             }
  //         }
  //     }
  // }
  //
  void check() {
    int sum = 0;
    for (int y = 0; y < 3; y++) {
      for (int z = 0; z < 3; z++) {
        // set<int> Rset;
        // for(int x = 0; x < 3; x++){
        //     Rset.insert(dice_R[ T[z][x] ][ F[y][x] ]);
        // }
        // if(Rset.size() != 1){
        //     // invalid face!
        //     return;
        // }
        // sum += *(Rset.begin());
        assert(dice_R[T[z][0]][F[y][0]] != 0);
        assert(dice_R[T[z][0]][F[y][0]] == dice_R[T[z][1]][F[y][1]]);
        assert(dice_R[T[z][1]][F[y][1]] == dice_R[T[z][2]][F[y][2]]);
        sum += dice_R[T[z][0]][F[y][0]];
      }
    }
    answer.insert(sum);
  }

  vector<int> solve() {
    answer.clear();
    rec_F(0, 0);
    vector<int> res(answer.begin(), answer.end());
    if (res.empty())
      res.push_back(0);
    return res;
  }
};

int main() {
  int Test;
  cin >> Test;
  while (Test--) {
    Solver s;
    vector<int> res = s.solve();
    for (int i = 0; i < res.size(); i++) {
      cout << res[i];
      if (i == res.size() - 1)
        cout << endl;
      else
        cout << " ";
    }
  }
  return 0;
}

Error: TLE

Fixed submission:

#include <bits/stdc++.h>
#define REP(i, n) for (int i = 0; i < (int)(n); ++i)

using namespace std;
struct Solver {
  int F[3][3];
  int T[3][3];
  int R[3][3];
  int dice_R[7][7]; // [TOP][FRONT] -> RIGHT

  enum FACE { TOP, BOTTOM, FRONT, BACK, LEFT, RIGHT };

  struct Dice {
    vector<int> val;
    Dice(vector<int> init) : val(init) { assert(val.size() == 6); }
    void roll_x() { roll(TOP, BACK, BOTTOM, FRONT); }
    void roll_y() { roll(TOP, LEFT, BOTTOM, RIGHT); }
    void roll_z() { roll(FRONT, RIGHT, BACK, LEFT); }
    void roll_r(int r) {
      if (r == 0)
        roll(TOP, LEFT, BOTTOM, RIGHT);
      if (r == 1)
        roll(TOP, BACK, BOTTOM, FRONT);
      if (r == 2)
        roll(TOP, RIGHT, BOTTOM, LEFT);
      if (r == 3)
        roll(TOP, FRONT, BOTTOM, BACK);
    }
    void roll(int a, int b, int c, int d) { // a, b, c, d -> b, c, d, a
      int tmp = val[a];
      val[a] = val[b];
      val[b] = val[c];
      val[c] = val[d];
      val[d] = tmp;
    }
  };

  Solver() {
    memset(F, 0, sizeof(F));
    memset(T, 0, sizeof(T));
    memset(R, 0, sizeof(R));

    /* input */
    REP(y, 3) REP(x, 3) cin >> T[y][x];
    REP(y, 3) REP(x, 3) cin >> F[y][x];

    Dice a(vector<int>({1, 6, 2, 5, 4, 3}));
    for (int i = 0; i < 6; i++) {
      for (int j = 0; j < 4; j++) {
        // printf("%d %d -> %d\\n", a.val[TOP], a.val[FRONT], a.val[RIGHT]);
        dice_R[a.val[TOP]][a.val[FRONT]] = a.val[RIGHT];
        a.roll_z();
      }
      if (i & 1)
        a.roll_x();
      else
        a.roll_y();
    }
  }

  set<int> answer;

  void rec_F(int x, int y) {
    // printf("F(%d, %d)\\n", x, y);
    if (y == 3) {
      rec_T(0, 0);
    } else {
      int nx = (x + 1 != 3 ? x + 1 : 0);
      int ny = (x + 1 != 3 ? y : y + 1);
      if (F[y][x] != 0) {
        rec_F(nx, ny);
      } else {
        for (int val = 1; val <= 6; val++) {
          bool ok = true;
          for (int z = 0; z < 3; z++) {
            if ((T[z][x] == val) || (7 - T[z][x] == val)) {
              ok = false;
            }
          }
          if (ok) {
            F[y][x] = val;
            rec_F(nx, ny);
            F[y][x] = 0;
          }
        }
      }
    }
  }

  void rec_T(int x, int z) {
    if (z == 3) {
      check();
    } else {
      int nx = (x + 1 != 3 ? x + 1 : 0);
      int nz = (x + 1 != 3 ? z : z + 1);
      if (T[z][x] != 0) {
        rec_T(nx, nz);
      } else {
        for (int val = 1; val <= 6; val++) {
          bool ok = true;
          for (int y = 0; y < 3; y++) {
            if ((F[y][x] == val) || (7 - F[y][x] == val)) {
              ok = false;
            }
          }
          if (ok) {
            T[z][x] = val;
            rec_T(nx, nz);
            T[z][x] = 0;
          }
        }
      }
    }
  }

  // void rec_R(int z, int y){
  //     if(y == 3){
  //     }else{
  //         int nz = (z + 1 != 3 ? z + 1 : 0);
  //         int ny = (z + 1 != 3 ? y : y + 1);
  //         assert(R[y][z] == 0);
  //         for(int val = 1; val <= 6; val++){
  //             bool ok = true;
  //             for(int x = 0; x < 3; x++){
  //                 if((F[y][x] == val) || (7 - F[y][x] == val)){
  //                     ok = false;
  //                 }
  //                 if((T[2 - z][x] == val) || (7 - T[2 - z][x] == val)){
  //                     ok = false;
  //                 }
  //             }
  //             if(ok){
  //                 R[y][z] = val;
  //                 rec_R(nz, ny);
  //                 R[y][z] = 0;
  //             }
  //         }
  //     }
  // }
  //
  void check() {
    int sum = 0;
    for (int y = 0; y < 3; y++) {
      for (int z = 0; z < 3; z++) {
        set<int> Rset;
        for (int x = 0; x < 3; x++) {
          Rset.insert(dice_R[T[z][x]][F[y][x]]);
        }
        if (Rset.size() != 1) {
          // invalid face!
          return;
        }
        sum += *(Rset.begin());
      }
    }
    answer.insert(sum);
  }

  vector<int> solve() {
    answer.clear();
    rec_F(0, 0);
    vector<int> res(answer.begin(), answer.end());
    if (res.empty())
      res.push_back(0);
    return res;
  }
};

int main() {
  int Test;
  cin >> Test;
  while (Test--) {
    Solver s;
    vector<int> res = s.solve();
    for (int i = 0; i < res.size(); i++) {
      cout << res[i];
      if (i == res.size() - 1)
        cout << endl;
      else
        cout << " ";
    }
  }
  return 0;
}