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

#include <bits/stdc++.h>
#define F first
#define S second
#define INF (1e9)
#define N 5
using namespace std;

typedef pair<vector<string>, int> P;
typedef pair<int, int> P1;
typedef pair<P, P1> P2;

vector<string> s;
int n, sy, sx;

bool check(vector<string> grid) {

  for (int i = 0; i < n; i++)
    for (int j = 0; j < n; j++)
      if (grid[i][j] == '#')
        return false;

  return true;
}

vector<string> infect(vector<string> grid) {

  vector<string> res(n, string(n, 'x'));

  for (int i = 0; i < n; i++) {
    for (int j = 0; j < n; j++) {

      int cnt = 0;

      for (int k = -1; k <= 1; k++) {
        for (int l = -1; l <= 1; l++) {

          if (k == 0 && l == 0)
            continue;

          int ni = i + k, nj = j + l;

          if (ni < 0 || nj < 0 || n <= ni || n <= nj)
            continue;
          if (grid[ni][nj] != '.')
            cnt++;
        }
      }

      if (grid[i][j] == '@')
        res[i][j] = '@';
      else if (grid[i][j] == '.') {
        if (cnt == 3)
          res[i][j] = '#';
        else
          res[i][j] = '.';
      } else {
        if (cnt == 2 || cnt == 3)
          res[i][j] = '#';
        else
          res[i][j] = '.';
      }
    }
  }

  return res;
}

int bfs() {

  map<vector<string>, int> memo;
  queue<P2> q;

  q.push(P2(P(s, 0), P1(sy, sx)));
  memo[s] = 0;

  while (!q.empty()) {

    P2 t = q.front();
    q.pop();

    vector<string> grid = t.F.F;

    int cost = t.F.S, y = t.S.F, x = t.S.S;

    if (check(grid))
      return cost;

    for (int i = -1; i <= 1; i++) {
      for (int j = -1; j <= 1; j++) {

        if (i == 0 && j == 0)
          continue;

        int ncost = cost + 1, ny = y + i, nx = x + j;

        if (ny < 0 || nx < 0 || n <= ny || n <= nx)
          continue;
        if (grid[ny][nx] == '#')
          continue;

        vector<string> ngrid = grid;

        swap(ngrid[y][x], ngrid[ny][nx]);

        ngrid = infect(ngrid);

        if (memo.count(ngrid))
          continue;

        memo[ngrid] = ncost;
        q.push(P2(P(ngrid, ncost), P1(ny, nx)));
      }
    }
  }

  return INF;
}

int main() {

  while (1) {

    cin >> n;
    if (!n)
      break;

    s.resize(n);

    for (int i = 0; i < n; i++) {
      cin >> s[i];

      for (int j = 0; j < n; j++)
        if (s[i][j] == '@')
          sy = i, sx = j;
    }

    int ans = bfs();

    cout << (ans == INF ? -1 : ans) << endl;
  }

  return 0;
}

Error: TLE

Fixed submission:

#include <bits/stdc++.h>
#define INF (1e9)
#define TOP 0
#define FRONT 1
#define LEFT 2
#define RIGHT 3
#define BACK 4
#define BOTTOM 5
#define N 30
using namespace std;

// TOP,FRONT,LEFT,RIGHT,BACK,BOTTOM
char dice[6];
char clist[6] = {'r', 'm', 'y', 'b', 'g', 'c'};

void init() {
  for (int i = 0; i < 6; i++)
    dice[i] = clist[i];
}

//?\\\\?????¢??????
void rotN() {
  swap(dice[TOP], dice[FRONT]);
  swap(dice[FRONT], dice[BOTTOM]);
  swap(dice[BOTTOM], dice[BACK]);
}

//???????????¢??????
void rotS() {
  // rotN(),rotN(),rotN();
  swap(dice[TOP], dice[BACK]);
  swap(dice[BACK], dice[BOTTOM]);
  swap(dice[BOTTOM], dice[FRONT]);
}

//????????¢??????
void rotE() {
  swap(dice[TOP], dice[LEFT]);
  swap(dice[LEFT], dice[BOTTOM]);
  swap(dice[BOTTOM], dice[RIGHT]);
}

//????????¢??????
void rotW() {
  // rotE(),rotE(),rotE();
  swap(dice[TOP], dice[RIGHT]);
  swap(dice[RIGHT], dice[BOTTOM]);
  swap(dice[BOTTOM], dice[LEFT]);
}

string s[N], t;
int h, w;
int ctoi[300];

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

int check(int ny, int nx, int p) {

  char c = s[ny][nx];

  if (c == 'k')
    return 2;

  if (c == 'w')
    return 0;

  if (c == t[p] && c == dice[TOP])
    return 1;
  return 2;
}

void Rot(int dir) {
  if (dir == 0)
    rotN();
  if (dir == 1)
    rotE();
  if (dir == 2)
    rotS();
  if (dir == 3)
    rotW();
}

struct dat {
  int cost, y, x, p;
  char dice[6];
  dat(){};
  dat(int a, int b, int c, int d) { cost = a, y = b, x = c, p = d; };
};

int d[N][N][6][6][6];

int bfs(int sy, int sx) {
  for (int i = 0; i < h; i++)
    for (int j = 0; j < w; j++)
      for (int k = 0; k < 6; k++)
        for (int l = 0; l < 6; l++)
          for (int m = 0; m < 6; m++)
            d[i][j][k][l][m] = INF;

  d[sy][sx][0][ctoi[dice[TOP]]][ctoi[dice[FRONT]]] = 0;

  queue<dat> q;

  dat A = dat(0, sy, sx, 0);
  for (int i = 0; i < 6; i++)
    A.dice[i] = dice[i];

  q.push(A);

  while (!q.empty()) {
    dat u = q.front();
    q.pop();

    if (d[u.y][u.x][u.p][ctoi[u.dice[TOP]]][ctoi[u.dice[FRONT]]] < u.cost)
      continue;
    if (u.p == t.size())
      return u.cost;

    for (int i = 0; i < 4; i++) {
      int ny = u.y + dy[i], nx = u.x + dx[i], ncost = u.cost + 1;

      if (ny < 0 || nx < 0 || h <= ny || w <= nx)
        continue;

      for (int j = 0; j < 6; j++)
        dice[j] = u.dice[j];

      Rot(i);
      for (int j = 0; j < 6; j++)
        u.dice[j] = dice[j];

      int r = check(ny, nx, u.p);

      int flag = 0;

      for (int j = 0; j < u.p; j++)
        if (s[ny][nx] != 'k' && s[ny][nx] != 'w' && s[ny][nx] == t[j])
          flag = 1;

      if (r == 2 || flag) {
        Rot(i);
        Rot(i);
        Rot(i);
        for (int j = 0; j < 6; j++)
          u.dice[j] = dice[j];
        continue;
      }

      if (d[ny][nx][u.p + r][ctoi[u.dice[TOP]]][ctoi[u.dice[FRONT]]] > ncost) {
        d[ny][nx][u.p + r][ctoi[u.dice[TOP]]][ctoi[u.dice[FRONT]]] = ncost;
        dat A = dat(ncost, ny, nx, u.p + r);
        for (int j = 0; j < 6; j++)
          A.dice[j] = u.dice[j];
        q.push(A);
      }

      Rot(i);
      Rot(i);
      Rot(i);
      for (int j = 0; j < 6; j++)
        u.dice[j] = dice[j];
    }
  }

  return INF;
}

int main() {
  ctoi['r'] = 0;
  ctoi['m'] = 1;
  ctoi['y'] = 2;
  ctoi['b'] = 3;
  ctoi['g'] = 4;
  ctoi['c'] = 5;

  while (1) {

    cin >> w >> h;
    if (!h && !w)
      break;

    int sy, sx;
    for (int i = 0; i < h; i++) {
      cin >> s[i];

      for (int j = 0; j < w; j++)
        if (s[i][j] == '#') {
          sy = i, sx = j;
          s[i][j] = 'w';
        }
    }
    cin >> t;

    init();
    int ans = bfs(sy, sx);

    if (ans == INF)
      cout << "unreachable" << endl;
    else
      cout << ans << endl;
  }
  return 0;
}