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

#include <bits/stdc++.h>
#define N 31
#define TOP 0
#define FRONT 1
#define LEFT 2
#define RIGHT 3
#define BACK 4
#define BOTTOM 5
using namespace std;
int w, h;
string mp[N];

void rotN(vector<char> &dice) {
  swap(dice[TOP], dice[FRONT]);
  swap(dice[FRONT], dice[BOTTOM]);
  swap(dice[BOTTOM], dice[BACK]);
}

void rotS(vector<char> &dice) { rotN(dice), rotN(dice), rotN(dice); }

void rotE(vector<char> &dice) {
  swap(dice[TOP], dice[LEFT]);
  swap(dice[LEFT], dice[BOTTOM]);
  swap(dice[BOTTOM], dice[RIGHT]);
}

void rotW(vector<char> &dice) { rotE(dice), rotE(dice), rotE(dice); }

void rotCW(vector<char> &dice) {
  swap(dice[FRONT], dice[RIGHT]);
  swap(dice[RIGHT], dice[BACK]);
  swap(dice[BACK], dice[LEFT]);
}

typedef pair<int, int> P;
typedef pair<vector<char>, P> PP;

int dx[] = {0, 0, 1, -1};
int dy[] = {1, -1, 0, 0};
string ord;

P getStart(char ch) {
  for (int i = 0; i < h; i++)
    for (int j = 0; j < w; j++)
      if (mp[i][j] == ch) {
        mp[i][j] = 'w';
        return P(j, i);
      }
}

int C[1 << 8];

int bfs(int sx, int sy, int gx, int gy, vector<char> dice, int dep) {
  char gch = ord[dep];

  int D[10][10][31][31];
  memset(D, -1, sizeof(D));

  D[C[dice[TOP]]][C[dice[FRONT]]][sx][sy] = 0;
  queue<PP> Q;
  Q.push(PP(dice, P(sx, sy)));

  int res = 1e9;
  while (!Q.empty()) {
    PP t = Q.front();
    Q.pop();
    dice = t.first;
    int x = t.second.first;
    int y = t.second.second;
    int cost = D[C[dice[TOP]]][C[dice[FRONT]]][x][y];

    if (x == gx && y == gy) {
      if (dice[TOP] != gch)
        continue;
      if (dep + 1 == (int)ord.size())
        return cost;
      P st = getStart(ord[dep + 1]);
      mp[gy][gx] = 'k';
      res = min(res, cost + bfs(gx, gy, st.first, st.second, dice, dep + 1));
      mp[st.second][st.first] = ord[dep + 1];
      mp[gy][gx] = 'w';
      continue;
    }

    for (int i = 0; i < 4; i++) {
      int nx = x + dx[i];
      int ny = y + dy[i];
      vector<char> ndice = dice;
      if (i == 0)
        rotS(ndice);
      if (i == 1)
        rotN(ndice);
      if (i == 2)
        rotE(ndice);
      if (i == 3)
        rotW(ndice);
      PP sta = PP(ndice, P(nx, ny));
      if (nx < 0 || ny < 0 || nx >= w || ny >= h || mp[ny][nx] != 'w')
        continue;
      if (D[C[ndice[TOP]]][C[ndice[FRONT]]][nx][ny] != -1)
        continue;
      Q.push(sta);
      D[C[ndice[TOP]]][C[ndice[FRONT]]][nx][ny] = cost + 1;
    }
  }
  return res;
}

int main() {
  while (1) {
    cin >> w >> h;
    if (!w && !h)
      break;
    for (int i = 0; i < h; i++)
      cin >> mp[i];
    cin >> ord;
    vector<char> dice(6);
    dice[TOP] = 'r';
    dice[BOTTOM] = 'c';
    dice[BACK] = 'g';
    dice[FRONT] = 'm';
    dice[RIGHT] = 'b';
    dice[LEFT] = 'y';
    C['r'] = 0;
    C['c'] = 1;
    C['g'] = 2;
    C['m'] = 3;
    C['b'] = 4;
    C['y'] = 5;

    P s = getStart('#');
    P g = getStart(ord[0]);
    int ans = bfs(s.first, s.second, g.first, g.second, dice, 0);

    if (ans < 1e9)
      cout << ans << endl;
    else
      cout << "unreachable" << endl;
  }
  return 0;
}

Error: TLE

Fixed submission:

#include <bits/stdc++.h>
#define N 31
#define TOP 0
#define FRONT 1
#define LEFT 2
#define RIGHT 3
#define BACK 4
#define BOTTOM 5
using namespace std;
int w, h;
string mp[N];

void rotN(vector<char> &dice) {
  swap(dice[TOP], dice[FRONT]);
  swap(dice[FRONT], dice[BOTTOM]);
  swap(dice[BOTTOM], dice[BACK]);
}

void rotS(vector<char> &dice) { rotN(dice), rotN(dice), rotN(dice); }

void rotE(vector<char> &dice) {
  swap(dice[TOP], dice[LEFT]);
  swap(dice[LEFT], dice[BOTTOM]);
  swap(dice[BOTTOM], dice[RIGHT]);
}

void rotW(vector<char> &dice) { rotE(dice), rotE(dice), rotE(dice); }

void rotCW(vector<char> &dice) {
  swap(dice[FRONT], dice[RIGHT]);
  swap(dice[RIGHT], dice[BACK]);
  swap(dice[BACK], dice[LEFT]);
}

typedef pair<int, int> P;
typedef pair<vector<char>, P> PP;

int dx[] = {0, 0, 1, -1};
int dy[] = {1, -1, 0, 0};
string ord;

P getStart(char ch) {
  for (int i = 0; i < h; i++)
    for (int j = 0; j < w; j++)
      if (mp[i][j] == ch) {
        mp[i][j] = 'w';
        return P(j, i);
      }
}

int bfs(int sx, int sy, int gx, int gy, vector<char> dice, int dep) {
  char gch = ord[dep];

  map<PP, int> D;
  D[PP(dice, P(sx, sy))] = 0;
  queue<PP> Q;
  Q.push(PP(dice, P(sx, sy)));

  int res = 1e9;
  while (!Q.empty()) {
    PP t = Q.front();
    Q.pop();
    dice = t.first;
    int x = t.second.first;
    int y = t.second.second;
    int cost = D[t];

    if (x == gx && y == gy) {
      if (dice[TOP] != gch)
        continue;
      if (dep + 1 == (int)ord.size())
        return cost;
      P st = getStart(ord[dep + 1]);
      mp[gy][gx] = 'k';
      res = min(res, cost + bfs(gx, gy, st.first, st.second, dice, dep + 1));
      mp[st.second][st.first] = ord[dep + 1];
      mp[gy][gx] = 'w';
      continue;
    }

    for (int i = 0; i < 4; i++) {
      int nx = x + dx[i];
      int ny = y + dy[i];
      vector<char> ndice = dice;
      if (i == 0)
        rotS(ndice);
      if (i == 1)
        rotN(ndice);
      if (i == 2)
        rotE(ndice);
      if (i == 3)
        rotW(ndice);
      PP sta = PP(ndice, P(nx, ny));
      if (nx < 0 || ny < 0 || nx >= w || ny >= h || mp[ny][nx] != 'w')
        continue;
      if (D.count(sta))
        continue;
      Q.push(sta);
      D[sta] = cost + 1;
    }
  }
  return res;
}

int main() {
  while (1) {
    cin >> w >> h;
    if (!w && !h)
      break;
    for (int i = 0; i < h; i++)
      cin >> mp[i];
    cin >> ord;
    vector<char> dice(6);
    dice[TOP] = 'r';
    dice[BOTTOM] = 'c';
    dice[BACK] = 'g';
    dice[FRONT] = 'm';
    dice[RIGHT] = 'b';
    dice[LEFT] = 'y';

    P s = getStart('#');
    P g = getStart(ord[0]);
    int ans = bfs(s.first, s.second, g.first, g.second, dice, 0);

    if (ans < 1e9)
      cout << ans << endl;
    else
      cout << "unreachable" << endl;
  }
  return 0;
}