Problem p01142 (C++) — buggy submission, verdict: Runtime Error

#define _USE_MATH_DEFINES
#define INF 0x3f3f3f3f
#include <algorithm>
#include <assert.h>
#include <bitset>
#include <cmath>
#include <complex>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <deque>
#include <iostream>
#include <limits>
#include <list>
#include <map>
#include <queue>
#include <set>
#include <sstream>
#include <stack>
#include <string>

using namespace std;

typedef long long ll;
typedef pair<int, int> P;

static const double EPS = 1e-12;

static const int tx[] = {+0, +1, +0, -1};
static const int ty[] = {-1, +0, +1, +0};

class State {
public:
  int forward_x;
  int forward_y;
  int forward_dir;
  int backward_x;
  int backward_y;
  int backward_dir;
  State(int fx, int fy, int fd, int bx, int by, int bd)
      : forward_x(fx), forward_y(fy), forward_dir(fd), backward_x(bx),
        backward_y(by), backward_dir(bd) {}
};

bool visited[17][65][4][17][65][4];
char stage[17][65];

bool two_doll_bfs(int sx, int sy, int sdir, int gx, int gy, int gdir) {
  queue<State> que;
  memset(visited, false, sizeof(visited));

  for (int bdir = 0; bdir < 4; bdir++) {
    visited[sy][sx][sdir][sy][sx][bdir] = true;
    que.push(State(sx, sy, sdir, sx, sy, bdir));
  }

  while (!que.empty()) {
    State s = que.front();
    que.pop();

    int tmp_forward_dx = s.forward_x;
    int tmp_forward_dy = s.forward_y;
    while (stage[tmp_forward_dy][tmp_forward_dx] != '#') {
      tmp_forward_dx += tx[s.forward_dir];
      tmp_forward_dy += ty[s.forward_dir];
    }
    tmp_forward_dx -= tx[s.forward_dir];
    tmp_forward_dy -= ty[s.forward_dir];

    int forward_dx = tmp_forward_dx;
    int forward_dy = tmp_forward_dy;

    int backward_dx = s.backward_x;
    int backward_dy = s.backward_y;

    while (stage[backward_dy][backward_dx] != '#') {

      if (visited[forward_dy][forward_dx][s.forward_dir][backward_dy]
                 [backward_dx][s.backward_dir]) {
        backward_dx += tx[(s.backward_dir + 2) % 4];
        backward_dy += ty[(s.backward_dir + 2) % 4];
        continue;
      }

      const int lr[] = {3, 1}; // {left,right}
      for (int i = 0; i < 2; i++) {
        if (stage[ty[(s.backward_dir + lr[i]) % 4] + backward_dy]
                 [tx[(s.backward_dir + lr[i]) % 4] + backward_dx] != '#')
          continue;
        visited[forward_dy][forward_dx][s.forward_dir][backward_dy][backward_dx]
               [s.backward_dir] = true;
        que.push(State(forward_dx, forward_dy, (s.forward_dir + lr[i]) % 4,
                       backward_dx, backward_dy, (s.backward_dir + lr[i]) % 4));
      }
      backward_dx += tx[(s.backward_dir + 2) % 4];
      backward_dy += ty[(s.backward_dir + 2) % 4];
    }
  }

  bool flag = false;
  for (int i = 0; i < 4; i++) {
    if (visited[gy][gx][i][gy][gx][gdir]) {
      flag = true;
      break;
    }
  }

  return flag;
}

bool one_doll_bfs(int sx, int sy, int sdir, int gx, int gy, int gdir) {
  queue<State> que;
  memset(visited, false, sizeof(visited));

  const int backward_dx = sx;
  const int backward_dy = sy;
  const int backward_dir = 0;

  que.push(State(sx, sy, sdir, backward_dx, backward_dy, backward_dir));

  while (!que.empty()) {
    State s = que.front();
    que.pop();

    int tmp_forward_dx = s.forward_x;
    int tmp_forward_dy = s.forward_y;

    while (stage[tmp_forward_dy][tmp_forward_dx] != '#') {
      tmp_forward_dx += tx[s.forward_dir];
      tmp_forward_dy += ty[s.forward_dir];
    }
    tmp_forward_dx -= tx[s.forward_dir];
    tmp_forward_dy -= ty[s.forward_dir];

    int forward_dx = tmp_forward_dx;
    int forward_dy = tmp_forward_dy;

    if (visited[forward_dy][forward_dx][s.forward_dir][backward_dy][backward_dx]
               [backward_dir])
      continue;
    visited[forward_dy][forward_dx][s.forward_dir][backward_dy][backward_dx]
           [backward_dir] = true;

    const int lr[] = {3, 1}; // {left,right}
    for (int i = 0; i < 2; i++) {
      que.push(State(forward_dx, forward_dy, (s.forward_dir + lr[i]) % 4,
                     backward_dx, backward_dy, backward_dir));
    }
  }

  bool flag = false;
  for (int i = 0; i < 4; i++) {
    if (visited[gy][gx][i][backward_dy][backward_dx][backward_dir]) {
      flag = true;
      break;
    }
  }

  return flag;
}

void disp(int W, int H) {
  for (int y = 0; y < H; y++) {
    for (int x = 0; x < W; x++) {
      printf("%c", stage[y][x]);
    }
    printf("\\n");
  }
  printf("\\n");
}

int main() {
  int W, H;
  while (~scanf("%d %d", &W, &H)) {
    if (W == 0 && H == 0)
      break;
    // memset(stage,'\\0',sizeof(stage));

    int sx, sy, sdir;
    int gx, gy, gdir;

    for (int y = 0; y < H; y++) {
      char line[128];
      scanf("%s", line);
      for (int x = 0; x < W; x++) {
        stage[y][x] = line[x];
        if (stage[y][x] == 'K') {
          sx = x;
          sy = y;
        }
        if (stage[y][x] == 'M') {
          gx = x;
          gy = y;
        }
      }
    }

    for (int i = 0; i < 4; i++) {
      if (stage[sy + ty[i]][sx + tx[i]] == '.') {
        sdir = i;
      }
      if (stage[gy + ty[i]][gx + tx[i]] == '.') {
        gdir = i;
      }
    }

    if (one_doll_bfs(sx, sy, sdir, gx, gy, gdir)) {
      if (two_doll_bfs(sx, sy, sdir, gx, gy, gdir)) {
        printf("He can accomplish his mission.\\n");
      } else {
        printf("He cannot return to the kitchen.\\n");
      }
    } else {
      printf("He cannot bring tea to his master.\\n");
    }
  }
}

Error: TLE

Fixed submission:

#define _USE_MATH_DEFINES
#define INF 0x3f3f3f3f
#include <algorithm>
#include <assert.h>
#include <bitset>
#include <cmath>
#include <complex>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <deque>
#include <iostream>
#include <limits>
#include <list>
#include <map>
#include <queue>
#include <set>
#include <sstream>
#include <stack>
#include <string>

using namespace std;

typedef long long ll;
typedef pair<int, int> P;

static const double EPS = 1e-12;

int tx[] = {+0, +1, +0, -1};
int ty[] = {-1, +0, +1, +0};

class State {
public:
  int x;
  int y;
  int cost;
  int dir;
  vector<int> commands;
  State(int x, int y, int cost, int dir) : x(x), y(y), cost(cost), dir(dir) {}
  State(int x, int y, int cost, int dir, const vector<int> &commands)
      : x(x), y(y), cost(cost), dir(dir), commands(commands) {}
  bool operator<(const State &s) const { return cost < s.cost; }
  bool operator>(const State &s) const { return cost > s.cost; }
};

int main() {
  int W, H;
  while (~scanf("%d %d", &W, &H)) {
    if (W == 0 && H == 0)
      break;
    char stage[20][70];
    int sx, sy;
    int gx, gy;
    for (int y = 0; y < H; y++) {
      char line[70];
      scanf("%s", line);
      for (int x = 0; x < W; x++) {
        stage[y][x] = line[x];
        if (stage[y][x] == 'K') {
          sx = x;
          sy = y;
        }
        if (stage[y][x] == 'M') {
          gx = x;
          gy = y;
        }
      }
    }

    priority_queue<State, vector<State>, greater<State>> que;
    que.push(State(sx, sy, 0, 0));
    bool visited[20][70][4] = {};
    int flag = 0;

    while (!que.empty()) {
      State s = que.top();
      que.pop();
      if (s.x == gx && s.y == gy) {
        flag |= (1 << 0);
        int dx = s.x;
        int dy = s.y;
        int dir = (s.dir + 2) % 4;
        while (true) {
          if (stage[dy + ty[dir]][dx + tx[dir]] == '#') {
            if (s.commands.size() == 0)
              break;
            dir = dir + (s.commands.back() == 0 ? 1 : 3);
            dir %= 4;
            s.commands.pop_back();
          } else {
            dy = dy + ty[dir];
            dx = dx + tx[dir];
          }
          if (dx == sx && dy == sy) {
            flag |= (1 << 1);
            break;
          }
        }
        continue;
      }

      for (int i = 0; i < 4; i++) {
        int dx = tx[s.dir] + s.x;
        int dy = ty[s.dir] + s.y;
        if (dy >= H || dx >= W || dy < 0 || dx < 0)
          continue;
        if (stage[dy][dx] == '#') {
          if (!visited[s.y][s.x][(s.dir + 1) % 4]) {
            vector<int> next = s.commands;
            next.push_back(1);
            visited[s.y][s.x][(s.dir + 1) % 4] = true;
            que.push(State(s.x, s.y, s.cost + 1, (s.dir + 1) % 4, next));
          }
          if (!visited[s.y][s.x][(s.dir + 3) % 4]) {
            vector<int> next = s.commands;
            next.push_back(0);
            visited[s.y][s.x][(s.dir + 3) % 4] = true;
            que.push(State(s.x, s.y, s.cost + 1, (s.dir + 3) % 4, next));
          }
        } else if (stage[dy][dx] == '.' || stage[dy][dx] == 'K' ||
                   stage[dy][dx] == 'M') {
          visited[dy][dx][s.dir] = true;
          que.push(State(dx, dy, s.cost + 1, s.dir, s.commands));
        }
      }
    }

    if (flag == (1 << 2) - 1) {
      printf("He can accomplish his mission.\\n");
    } else if (flag == (1 << 0)) {
      printf("He cannot return to the kitchen.\\n");
    } else {
      printf("He cannot bring tea to his master.\\n");
    }
  }
}