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

#include <cstdio>
#include <queue>

#define rep(i, n) for (int i = 0; i < (n); i++)

using namespace std;

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

struct state {
  int i, j, k; // 行きの y 座標, x 座標, 向き
};

struct state2 {
  int i, j, k, y, x,
      d; // 行きの y 座標, x 座標, 向き, 帰りの y 座標, x 座標, 向き
};

int h, w;
char B[16][65];

void go_straight(int i, int j, int k, int &i2, int &j2) {
  while (B[i + dy[k]][j + dx[k]] == '.')
    i += dy[k], j += dx[k];
  i2 = i, j2 = j;
}

void turn_left(int i, int j, int k, int &i2, int &j2, int &k2) {
  k = (k + 1) % 4;
  while (B[i + dy[k]][j + dx[k]] == '.')
    i += dy[k], j += dx[k];
  i2 = i, j2 = j, k2 = k;
}

void turn_right(int i, int j, int k, int &i2, int &j2, int &k2) {
  k = (k + 3) % 4;
  while (B[i + dy[k]][j + dx[k]] == '.')
    i += dy[k], j += dx[k];
  i2 = i, j2 = j, k2 = k;
}

int main() {
  while (scanf("%d%d", &w, &h), w) {
    rep(i, h) scanf("%s", B[i]);

    int sx, sy, gx, gy;
    rep(i, h) rep(j, w) {
      if (B[i][j] == 'K')
        sx = j, sy = i, B[i][j] = '.';
      if (B[i][j] == 'M')
        gx = j, gy = i, B[i][j] = '.';
    }
    int gk;
    rep(k, 4) if (B[gy + dy[k]][gx + dx[k]] == '.') gk = k;

    bool ok = false;
    {
      static bool vis[16][64][4];
      rep(i, h) rep(j, w) rep(k, 4) vis[i][j][k] = false;

      queue<state> Q;
      rep(k, 4) {
        int yy = sy + dy[k], xx = sx + dx[k];
        if (B[yy][xx] == '.') {
          go_straight(yy, xx, k, yy, xx);
          vis[yy][xx][k] = true;
          Q.push((state){yy, xx, k});
        }
      }
      while (!Q.empty()) {
        state S = Q.front();
        Q.pop();
        int i = S.i, j = S.j, k = S.k;

        if (i == gy && j == gx) {
          ok = true;
          break;
        }

        int i2, j2, k2;
        turn_left(i, j, k, i2, j2, k2);
        if (!vis[i2][j2][k2]) {
          vis[i2][j2][k2] = true;
          Q.push((state){i2, j2, k2});
        }

        turn_right(i, j, k, i2, j2, k2);
        if (!vis[i2][j2][k2]) {
          vis[i2][j2][k2] = true;
          Q.push((state){i2, j2, k2});
        }
      }
    }
    if (!ok) {
      puts("He cannot bring tea to his master.");
      continue;
    }

    ok = false;
    {
      vector<state> from_L[16][64][4], from_R[16][64][4];
      rep(i, h) rep(j, w) if (B[i][j] == '.') rep(k, 4) {
        int y, x, d;
        turn_left(i, j, k, y, x, d);
        from_L[y][x][d].push_back((state){i, j, k});
        turn_right(i, j, k, y, x, d);
        from_R[y][x][d].push_back((state){i, j, k});
      }

      static bool vis[16][64][4][16][64][4];
      rep(i, h) rep(j, w) rep(k, 4) rep(y, h) rep(x, w) rep(d, 4)
          vis[i][j][k][y][x][d] = false;

      queue<state2> Q;
      rep(k, 4) {
        int yy = sy + dy[k], xx = sx + dx[k];
        if (B[yy][xx] == '.') {
          go_straight(yy, xx, k, yy, xx);
          rep(kk, 4) if (kk != k) {
            vis[yy][xx][k][sy][sx][kk] = true;
            Q.push((state2){yy, xx, k, sy, sx, kk});
          }
        }
      }
      while (!Q.empty()) {
        state2 S = Q.front();
        Q.pop();
        int i = S.i, j = S.j, k = S.k, y = S.y, x = S.x, d = S.d;

        if (i == gy && j == gx) {
          int yy, xx;
          go_straight(gy, gx, gk, yy, xx);
          if (y == yy && x == xx && d == gk) {
            ok = true;
            break;
          }
        }

        int i2, j2, k2;
        turn_left(i, j, k, i2, j2, k2);
        rep(t, from_R[y][x][d].size()) {
          int y2 = from_R[y][x][d][t].i;
          int x2 = from_R[y][x][d][t].j;
          int d2 = from_R[y][x][d][t].k;
          if (!vis[i2][j2][k2][y2][x2][d2]) {
            vis[i2][j2][k2][y2][x2][d2] = true;
            Q.push((state2){i2, j2, k2, y2, x2, d2});
          }
        }

        turn_right(i, j, k, i2, j2, k2);
        rep(t, from_L[y][x][d].size()) {
          int y2 = from_L[y][x][d][t].i;
          int x2 = from_L[y][x][d][t].j;
          int d2 = from_L[y][x][d][t].k;
          if (!vis[i2][j2][k2][y2][x2][d2]) {
            vis[i2][j2][k2][y2][x2][d2] = true;
            Q.push((state2){i2, j2, k2, y2, x2, d2});
          }
        }
      }
    }

    if (ok)
      puts("He can accomplish his mission.");
    else
      puts("He cannot return to the kitchen.");
  }

  return 0;
}

Error: TLE

Fixed submission:

#include <cstdio>
#include <queue>

#define rep(i, n) for (int i = 0; i < (n); i++)

using namespace std;

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

struct state {
  int i, j, k; // 行きの y 座標, x 座標, 向き
};

struct state2 {
  int i, j, k, y, x,
      d; // 行きの y 座標, x 座標, 向き, 帰りの y 座標, x 座標, 向き
};

int h, w;
char B[16][65];

void go_straight(int i, int j, int k, int &i2, int &j2) {
  while (B[i + dy[k]][j + dx[k]] == '.')
    i += dy[k], j += dx[k];
  i2 = i, j2 = j;
}

void turn_left(int i, int j, int k, int &i2, int &j2, int &k2) {
  k = (k + 1) % 4;
  while (B[i + dy[k]][j + dx[k]] == '.')
    i += dy[k], j += dx[k];
  i2 = i, j2 = j, k2 = k;
}

void turn_right(int i, int j, int k, int &i2, int &j2, int &k2) {
  k = (k + 3) % 4;
  while (B[i + dy[k]][j + dx[k]] == '.')
    i += dy[k], j += dx[k];
  i2 = i, j2 = j, k2 = k;
}

int main() {
  while (scanf("%d%d", &w, &h), w) {
    rep(i, h) scanf("%s", B[i]);

    int sx, sy, gx, gy;
    rep(i, h) rep(j, w) {
      if (B[i][j] == 'K')
        sx = j, sy = i, B[i][j] = '.';
      if (B[i][j] == 'M')
        gx = j, gy = i, B[i][j] = '.';
    }
    int gk;
    rep(k, 4) if (B[gy + dy[k]][gx + dx[k]] == '.') gk = k;

    bool ok = false;
    {
      static bool vis[16][64][4];
      rep(i, h) rep(j, w) rep(k, 4) vis[i][j][k] = false;

      queue<state> Q;
      rep(k, 4) {
        int yy = sy + dy[k], xx = sx + dx[k];
        if (B[yy][xx] == '.') {
          go_straight(yy, xx, k, yy, xx);
          vis[yy][xx][k] = true;
          Q.push((state){yy, xx, k});
        }
      }
      while (!Q.empty()) {
        state S = Q.front();
        Q.pop();
        int i = S.i, j = S.j, k = S.k;

        if (i == gy && j == gx) {
          ok = true;
          break;
        }

        int i2, j2, k2;
        turn_left(i, j, k, i2, j2, k2);
        if (!vis[i2][j2][k2]) {
          vis[i2][j2][k2] = true;
          Q.push((state){i2, j2, k2});
        }

        turn_right(i, j, k, i2, j2, k2);
        if (!vis[i2][j2][k2]) {
          vis[i2][j2][k2] = true;
          Q.push((state){i2, j2, k2});
        }
      }
    }
    if (!ok)
      puts("He cannot bring tea to his master.");

    ok = false;
    {
      static bool vis[16][64][4][16][64][4];
      rep(i, h) rep(j, w) rep(k, 4) rep(y, h) rep(x, w) rep(d, 4)
          vis[i][j][k][y][x][d] = false;

      queue<state2> Q;
      rep(k, 4) {
        int yy = sy + dy[k], xx = sx + dx[k];
        if (B[yy][xx] == '.') {
          go_straight(yy, xx, k, yy, xx);
          rep(kk, 4) if (kk != k) {
            vis[yy][xx][k][sy][sx][kk] = true;
            Q.push((state2){yy, xx, k, sy, sx, kk});
          }
        }
      }
      while (!Q.empty()) {
        state2 S = Q.front();
        Q.pop();
        int i = S.i, j = S.j, k = S.k, y = S.y, x = S.x, d = S.d;

        if (i == gy && j == gx) {
          int yy, xx;
          go_straight(gy, gx, gk, yy, xx);
          if (y == yy && x == xx && d == gk) {
            ok = true;
            break;
          }
        }

        int i2, j2, k2;
        turn_left(i, j, k, i2, j2, k2);
        rep(y2, h) rep(x2, w) rep(d2, 4) if (B[y2][x2] == '.') {
          int yy, xx, dd;
          turn_right(y2, x2, d2, yy, xx, dd);
          if (yy == y && xx == x && dd == d && !vis[i2][j2][k2][y2][x2][d2]) {
            vis[i2][j2][k2][y2][x2][d2] = true;
            Q.push((state2){i2, j2, k2, y2, x2, d2});
          }
        }

        turn_right(i, j, k, i2, j2, k2);
        rep(y2, h) rep(x2, w) rep(d2, 4) if (B[y2][x2] == '.') {
          int yy, xx, dd;
          turn_left(y2, x2, d2, yy, xx, dd);
          if (yy == y && xx == x && dd == d && !vis[i2][j2][k2][y2][x2][d2]) {
            vis[i2][j2][k2][y2][x2][d2] = true;
            Q.push((state2){i2, j2, k2, y2, x2, d2});
          }
        }
      }
    }

    if (ok)
      puts("He can accomplish his mission.");
    else
      puts("He cannot return to the kitchen.");
  }

  return 0;
}