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

#include <algorithm>
#include <assert.h>
#include <iostream>
#include <map>
#include <math.h>
#include <queue>
#include <set>
#include <stdio.h>
#include <string.h>
#include <vector>

using namespace std;
typedef long long ll;
typedef unsigned int uint;
typedef unsigned long long ull;
static const double EPS = 1e-9;
static const double PI = acos(-1.0);

#define REP(i, n) for (int i = 0; i < (int)(n); i++)
#define FOR(i, s, n) for (int i = (s); i < (int)(n); i++)
#define FOREQ(i, s, n) for (int i = (s); i <= (int)(n); i++)
#define FORIT(it, c)                                                           \\
  for (__typeof((c).begin()) it = (c).begin(); it != (c).end(); it++)
#define MEMSET(v, h) memset((v), h, sizeof(v))

struct Face {
  char face[3][3];
  bool operator<(const Face &rhs) const {
    REP(y, 3) REP(x, 3) {
      if (face[y][x] != rhs.face[y][x]) {
        return face[y][x] < rhs.face[y][x];
      }
    }
    return false;
  }
  bool operator!=(const Face &rhs) const { return *this < rhs || rhs < *this; }
};

void rotation(Face &f, int x) {
  if (x == 0) {
    return;
  }
  Face ret;
  REP(y, 3) REP(x, 3) { ret.face[y][x] = f.face[2 - x][y]; }
  f = ret;
  rotation(f, x - 1);
}

void reverse(Face &f) {
  Face ret;
  REP(y, 3) REP(x, 3) { ret.face[y][x] = f.face[2 - y][x]; }
  f = ret;
}

struct Dice {
  Face face[6];
  bool operator<(const Dice &rhs) const {
    REP(i, 6) {
      if (face[i] != rhs.face[i]) {
        return face[i] < rhs.face[i];
      }
    }
    return false;
  }
};

Dice rotation(const Dice &d, int dir, int x) {
  if (x == 0) {
    return d;
  }
  Dice ret = d;
  if (dir >= 2) {
    return rotation(ret, dir - 2, 4 - x);
  }
  if (dir == 0) {
    ret.face[0] = d.face[5];
    rotation(ret.face[0], 0);
    ret.face[1] = d.face[1];
    rotation(ret.face[1], 1);
    ret.face[2] = d.face[4];
    rotation(ret.face[2], 2);
    ret.face[3] = d.face[3];
    rotation(ret.face[3], 3);
    ret.face[4] = d.face[0];
    rotation(ret.face[4], 0);
    ret.face[5] = d.face[2];
    rotation(ret.face[5], 2);
  } else {
    ret.face[0] = d.face[0];
    rotation(ret.face[0], 1);
    ret.face[1] = d.face[4];
    rotation(ret.face[1], 3);
    ret.face[2] = d.face[2];
    rotation(ret.face[2], 3);
    ret.face[3] = d.face[5];
    rotation(ret.face[3], 3);
    ret.face[4] = d.face[3];
    rotation(ret.face[4], 3);
    ret.face[5] = d.face[1];
    rotation(ret.face[5], 1);
  }
  return rotation(ret, dir, x - 1);
}

bool ok(const Dice &d) {
  bool ret1 = false;
  bool ret2 = false;
  REP(x, 3) {
    ret1 |= d.face[0].face[2][x] == '*';
    ret2 |= d.face[2].face[2][x] == '*';
  }
  return ret1 && ret2;
}

void print(const Dice &d) {
  REP(iter, 6) {
    REP(y, 3) {
      REP(x, 3) { putchar(d.face[iter].face[y][x]); }
      puts("");
    }
  }
  puts("");
}

set<Dice> visit;

int calc(Dice d) {
  queue<pair<Dice, int>> que;
  que.push(make_pair(d, 0));
  int ret = 10000;
  while (!que.empty()) {
    d = que.front().first;
    int c = que.front().second;
    que.pop();
    if (visit.count(d)) {
      continue;
    }
    visit.insert(d);
    if (ok(d)) {
      ret = c;
      break;
    }
    REP(dir, 4) {
      Dice nd = rotation(d, dir, 1);
      que.push(make_pair(nd, c + 1));
    }
  }
  return ret;
}

int main() {
  while (true) {
    visit.clear();
    Dice d;
    REP(iter, 6) {
      REP(y, 3) REP(x, 3) {
        char c;
        scanf(" %c ", &c);
        if (c == '#') {
          return 0;
        }
        d.face[iter].face[y][x] = c;
      }
    }
    printf("%d\\n", calc(d));
  }
}

Error: TLE

Fixed submission:

#include <algorithm>
#include <assert.h>
#include <iostream>
#include <map>
#include <math.h>
#include <queue>
#include <set>
#include <stdio.h>
#include <string.h>
#include <vector>

using namespace std;
typedef long long ll;
typedef unsigned int uint;
typedef unsigned long long ull;
static const double EPS = 1e-9;
static const double PI = acos(-1.0);

#define REP(i, n) for (int i = 0; i < (int)(n); i++)
#define FOR(i, s, n) for (int i = (s); i < (int)(n); i++)
#define FOREQ(i, s, n) for (int i = (s); i <= (int)(n); i++)
#define FORIT(it, c)                                                           \\
  for (__typeof((c).begin()) it = (c).begin(); it != (c).end(); it++)
#define MEMSET(v, h) memset((v), h, sizeof(v))

struct Face {
  char face[3][3];
  bool operator<(const Face &rhs) const {
    REP(y, 3) REP(x, 3) {
      if (face[y][x] != rhs.face[y][x]) {
        return face[y][x] < rhs.face[y][x];
      }
    }
    return false;
  }
  bool operator!=(const Face &rhs) const { return *this < rhs || rhs < *this; }
};

void rotation(Face &f, int x) {
  if (x == 0) {
    return;
  }
  Face ret;
  REP(y, 3) REP(x, 3) { ret.face[y][x] = f.face[2 - x][y]; }
  f = ret;
  rotation(f, x - 1);
}

void reverse(Face &f) {
  Face ret;
  REP(y, 3) REP(x, 3) { ret.face[y][x] = f.face[2 - y][x]; }
  f = ret;
}

struct Dice {
  Face face[6];
  bool operator<(const Dice &rhs) const {
    REP(i, 6) {
      if (face[i] != rhs.face[i]) {
        return face[i] < rhs.face[i];
      }
    }
    return false;
  }
};

Dice rotation(const Dice &d, int dir, int x) {
  if (x == 0) {
    return d;
  }
  Dice ret = d;
  if (dir >= 2) {
    return rotation(ret, dir - 2, 4 - x);
  }
  if (dir == 0) {
    ret.face[0] = d.face[5];
    rotation(ret.face[0], 0);
    ret.face[1] = d.face[1];
    rotation(ret.face[1], 1);
    ret.face[2] = d.face[4];
    rotation(ret.face[2], 2);
    ret.face[3] = d.face[3];
    rotation(ret.face[3], 1);
    ret.face[4] = d.face[0];
    rotation(ret.face[4], 0);
    ret.face[5] = d.face[2];
    rotation(ret.face[5], 2);
  } else {
    ret.face[0] = d.face[0];
    rotation(ret.face[0], 1);
    ret.face[1] = d.face[4];
    rotation(ret.face[1], 3);
    ret.face[2] = d.face[2];
    rotation(ret.face[2], 1);
    ret.face[3] = d.face[5];
    rotation(ret.face[3], 1);
    ret.face[4] = d.face[3];
    rotation(ret.face[4], 3);
    ret.face[5] = d.face[1];
    rotation(ret.face[5], 1);
  }
  return rotation(ret, dir, x - 1);
}

bool ok(const Dice &d) {
  bool ret1 = false;
  bool ret2 = false;
  REP(x, 3) {
    ret1 |= d.face[0].face[2][x] == '*';
    ret2 |= d.face[2].face[2][x] == '*';
  }
  return ret1 && ret2;
}

void print(const Dice &d) {
  REP(iter, 6) {
    REP(y, 3) {
      REP(x, 3) { putchar(d.face[iter].face[y][x]); }
      puts("");
    }
  }
  puts("");
}

set<Dice> visit;

int calc(Dice d) {
  queue<pair<Dice, int>> que;
  que.push(make_pair(d, 0));
  int ret = 0;
  while (!que.empty()) {
    d = que.front().first;
    int c = que.front().second;
    que.pop();
    if (visit.count(d)) {
      continue;
    }
    if (ok(d)) {
      ret = c;
      break;
    }
    REP(dir, 4) {
      Dice nd = rotation(d, dir, 1);
      que.push(make_pair(nd, c + 1));
    }
  }
  return ret;
}

int main() {
  while (true) {
    visit.clear();
    Dice d;
    REP(iter, 6) {
      REP(y, 3) REP(x, 3) {
        char c;
        scanf(" %c ", &c);
        if (c == '#') {
          return 0;
        }
        d.face[iter].face[y][x] = c;
      }
    }
    printf("%d\\n", calc(d));
  }
}