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

#include <algorithm>
#include <cassert>
#include <cctype>
#include <climits>
#include <cmath>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <ctime>
#include <deque>
#include <functional>
#include <iostream>
#include <list>
#include <map>
#include <queue>
#include <set>
#include <sstream>
#include <stack>
#include <string>
#include <utility>
#include <vector>
using namespace std;
inline int toInt(string s) {
  int v;
  istringstream sin(s);
  sin >> v;
  return v;
}
template <class T> inline string toString(T x) {
  ostringstream sout;
  sout << x;
  return sout.str();
}
typedef vector<int> vi;
typedef vector<vi> vvi;
typedef vector<string> vs;
typedef pair<int, int> pii;
typedef long long ll;
#define ALL(a) (a).begin(), (a).end()
#define RALL(a) (a).rbegin(), (a).rend()
#define EXIST(s, e) ((s).find(e) != (s).end())
#define FOR(i, a, b) for (int i = (a); i < (b); ++i)
#define REP(i, n) FOR(i, 0, n)
#define EACH(t, i, c) for (t::iterator i = (c).begin(); i != (c).end(); ++i)
const double EPS = 1e-10;
const double PI = acos(-1.0);

struct node {
  int y1, x1, y2, x2, dir1, dir2;
  node(int y1, int x1, int dir1, int y2, int x2, int dir2)
      : y1(y1), x1(x1), dir1(dir1), y2(y2), x2(x2), dir2(dir2) {}
};

static bool visited[16][64][4][16][64][5];

const int MAX = INT_MAX / 10;
const int NONE = -1;
int dx[] = {-1, 0, 1, 0}, dy[] = {0, -1, 0, 1};
int main() {
  int h, w;
  while (cin >> w >> h, w | h) {
    vs f(h);
    pii kichen, master;
    int k_dir, m_dir;
    REP(i, h) { cin >> f[i]; }
    REP(i, h) {
      REP(j, w) {
        if (f[i][j] == 'K') {
          kichen = make_pair(i, j);
          REP(d, 4) {
            int yy = i + dy[d];
            int xx = j + dx[d];
            if (f[yy][xx] == '.') {
              k_dir = d;
            }
          }
        }
        if (f[i][j] == 'M') {
          master = make_pair(i, j);
          REP(d, 4) {
            int yy = i + dy[d];
            int xx = j + dx[d];
            if (f[yy][xx] == '.') {
              m_dir = d;
            }
          }
        }
      }
    }

    stack<node> q;
    int sy, sx;
    for (int i = 1;; i++) {
      int cy = kichen.first + dy[k_dir] * (i - 1);
      int cx = kichen.second + dx[k_dir] * (i - 1);
      int ny = kichen.first + dy[k_dir] * i;
      int nx = kichen.second + dx[k_dir] * i;
      if (ny >= 0 && nx >= 0 && ny < h && nx < w && f[ny][nx] == '#') {
        sy = cy;
        sx = cx;
        break;
      }
    }
    REP(i, h) REP(j, w) REP(k, 4) REP(l, h) REP(m, w) REP(n, 5) {
      visited[i][j][k][l][m][n] = 0;
    }
    FOR(i, 1, 3 + 1) {
      q.push(node(sy, sx, k_dir, kichen.first, kichen.second, (k_dir + i) % 4));
      visited[sy][sx][k_dir][kichen.first][kichen.second][(k_dir + i) % 4] = 1;
    }
    while (!q.empty()) {
      node cnode = q.top();
      q.pop();
      for (int d = 1; d <= 3; d += 2) {
        vector<pii> points;
        int dir1 = (cnode.dir1 + d) % 4;
        int sy1, sx1;
        for (int i = 1;; i++) {
          int cy = cnode.y1 + dy[dir1] * (i - 1);
          int cx = cnode.x1 + dx[dir1] * (i - 1);
          int ny = cnode.y1 + dy[dir1] * i;
          int nx = cnode.x1 + dx[dir1] * i;
          if (ny >= 0 && nx >= 0 && ny < h && nx < w && f[ny][nx] == '#') {
            sy1 = cy;
            sx1 = cx;
            break;
          }
        }
        if (cnode.dir2 != 4) {
          int dir2 = (cnode.dir2 + d) % 4;
          for (int i = 1;; i++) {
            int cy = cnode.y2 + dy[(cnode.dir2 + 2) % 4] * (i - 1);
            int cx = cnode.x2 + dx[(cnode.dir2 + 2) % 4] * (i - 1);
            int ny = cnode.y2 + dy[(cnode.dir2 + 2) % 4] * i;
            int nx = cnode.x2 + dx[(cnode.dir2 + 2) % 4] * i;
            int sidey = cy + dy[dir2 % 4];
            int sidex = cx + dx[dir2 % 4];
            if (sidey >= 0 && sidex >= 0 && sidey < h && sidex < w &&
                f[sidey][sidex] == '#') {
              points.push_back(make_pair(cy, cx));
            }
            if (ny >= 0 && nx >= 0 && ny < h && nx < w && f[ny][nx] == '#') {
              break;
            }
          }

          REP(j, points.size()) {
            if (!visited[sy1][sx1][dir1][points[j].first][points[j].second]
                        [dir2]) {
              visited[sy1][sx1][dir1][points[j].first][points[j].second][dir2] =
                  1;
              q.push(node(sy1, sx1, dir1, points[j].first, points[j].second,
                          dir2));
            }
          }
        }
        if (!visited[sy1][sx1][dir1][0][0][4]) {
          visited[sy1][sx1][dir1][0][0][4] = 1;
          q.push(node(sy1, sx1, dir1, 0, 0, 4));
        }
      }
    }

    bool ac = false;
    for (int i = 1;; i++) {
      int cy = master.first + dy[m_dir] * (i - 1);
      int cx = master.second + dx[m_dir] * (i - 1);
      int ny = master.first + dy[m_dir] * i;
      int nx = master.second + dx[m_dir] * i;
      if (ny >= 0 && nx >= 0 && ny < h && nx < w && f[ny][nx] == '#') {
        sy = cy;
        sx = cx;
        break;
      }
    }
    for (int i = 1; i <= 3; i++) {
      if (visited[master.first][master.second][(m_dir + i) % 4][sy][sx]
                 [m_dir]) {
        ac = true;
      }
    }
    if (ac) {
      cout << "He can accomplish his mission." << endl;
      goto end;
    } else {
      bool flag = false;
      REP(i, h) REP(j, w) REP(d, 5) FOR(d1, 1, 4) {
        if (visited[master.first][master.second][(m_dir + d1) % 4][i][j][d]) {
          flag = true;
          break;
        }
      }
      if (flag) {
        cout << "He cannot return to the kitchen." << endl;
      } else {
        cout << "He cannot bring tea to his master." << endl;
      }
    }
  end:;
  }
}

Error: MLE

Fixed submission:

#include <algorithm>
#include <cassert>
#include <cctype>
#include <climits>
#include <cmath>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <ctime>
#include <deque>
#include <functional>
#include <iostream>
#include <list>
#include <map>
#include <queue>
#include <set>
#include <sstream>
#include <stack>
#include <string>
#include <utility>
#include <vector>
using namespace std;
inline int toInt(string s) {
  int v;
  istringstream sin(s);
  sin >> v;
  return v;
}
template <class T> inline string toString(T x) {
  ostringstream sout;
  sout << x;
  return sout.str();
}
typedef vector<int> vi;
typedef vector<vi> vvi;
typedef vector<string> vs;
typedef pair<int, int> pii;
typedef long long ll;
#define ALL(a) (a).begin(), (a).end()
#define RALL(a) (a).rbegin(), (a).rend()
#define EXIST(s, e) ((s).find(e) != (s).end())
#define FOR(i, a, b) for (int i = (a); i < (b); ++i)
#define REP(i, n) FOR(i, 0, n)
#define EACH(t, i, c) for (t::iterator i = (c).begin(); i != (c).end(); ++i)
const double EPS = 1e-10;
const double PI = acos(-1.0);

struct node {
  int y1, x1, y2, x2, dir1, dir2;
  node(int y1, int x1, int dir1, int y2, int x2, int dir2)
      : y1(y1), x1(x1), dir1(dir1), y2(y2), x2(x2), dir2(dir2) {}
};

typedef vector<vvi> vvvi;
typedef vector<vvvi> vvvvi;
typedef vector<vvvvi> vvvvvi;
typedef vector<vvvvvi> vvvvvvi;
const int MAX = INT_MAX / 10;
const int NONE = -1;
int dx[] = {-1, 0, 1, 0}, dy[] = {0, -1, 0, 1};
int main() {
  int h, w;
  while (cin >> w >> h, w | h) {
    vs f(h);
    pii kichen, master;
    int k_dir, m_dir;
    REP(i, h) { cin >> f[i]; }
    REP(i, h) {
      REP(j, w) {
        if (f[i][j] == 'K') {
          kichen = make_pair(i, j);
          REP(d, 4) {
            int yy = i + dy[d];
            int xx = j + dx[d];
            if (f[yy][xx] == '.') {
              k_dir = d;
            }
          }
        }
        if (f[i][j] == 'M') {
          master = make_pair(i, j);
          REP(d, 4) {
            int yy = i + dy[d];
            int xx = j + dx[d];
            if (f[yy][xx] == '.') {
              m_dir = d;
            }
          }
        }
      }
    }

    stack<node> q;
    vvvvvvi visited(h, vvvvvi(w, vvvvi(4, vvvi(h, vvi(w, vi(5))))));
    int sy, sx;
    for (int i = 1;; i++) {
      int cy = kichen.first + dy[k_dir] * (i - 1);
      int cx = kichen.second + dx[k_dir] * (i - 1);
      int ny = kichen.first + dy[k_dir] * i;
      int nx = kichen.second + dx[k_dir] * i;
      if (ny >= 0 && nx >= 0 && ny < h && nx < w && f[ny][nx] == '#') {
        sy = cy;
        sx = cx;
        break;
      }
    }
    FOR(i, 1, 3 + 1) {
      q.push(node(sy, sx, k_dir, kichen.first, kichen.second, (k_dir + i) % 4));
      visited[sy][sx][k_dir][kichen.first][kichen.second][(k_dir + i) % 4] = 1;
    }
    while (!q.empty()) {
      node cnode = q.top();
      q.pop();
      for (int d = 1; d <= 3; d += 2) {
        vector<pii> points;
        int dir1 = (cnode.dir1 + d) % 4;
        int sy1, sx1;
        for (int i = 1;; i++) {
          int cy = cnode.y1 + dy[dir1] * (i - 1);
          int cx = cnode.x1 + dx[dir1] * (i - 1);
          int ny = cnode.y1 + dy[dir1] * i;
          int nx = cnode.x1 + dx[dir1] * i;
          if (ny >= 0 && nx >= 0 && ny < h && nx < w && f[ny][nx] == '#') {
            sy1 = cy;
            sx1 = cx;
            break;
          }
        }
        if (cnode.dir2 != 4) {
          int dir2 = (cnode.dir2 + d) % 4;
          for (int i = 1;; i++) {
            int cy = cnode.y2 + dy[(cnode.dir2 + 2) % 4] * (i - 1);
            int cx = cnode.x2 + dx[(cnode.dir2 + 2) % 4] * (i - 1);
            int ny = cnode.y2 + dy[(cnode.dir2 + 2) % 4] * i;
            int nx = cnode.x2 + dx[(cnode.dir2 + 2) % 4] * i;
            int sidey = cy + dy[dir2 % 4];
            int sidex = cx + dx[dir2 % 4];
            if (sidey >= 0 && sidex >= 0 && sidey < h && sidex < w &&
                f[sidey][sidex] == '#') {
              points.push_back(make_pair(cy, cx));
            }
            if (ny >= 0 && nx >= 0 && ny < h && nx < w && f[ny][nx] == '#') {
              break;
            }
          }

          REP(j, points.size()) {
            if (!visited[sy1][sx1][dir1][points[j].first][points[j].second]
                        [dir2]) {
              visited[sy1][sx1][dir1][points[j].first][points[j].second][dir2] =
                  1;
              q.push(node(sy1, sx1, dir1, points[j].first, points[j].second,
                          dir2));
            }
          }
        }
        if (!visited[sy1][sx1][dir1][0][0][4]) {
          visited[sy1][sx1][dir1][0][0][4] = 1;
          q.push(node(sy1, sx1, dir1, 0, 0, 4));
        }
      }
    }

    bool ac = false;
    for (int i = 1;; i++) {
      int cy = master.first + dy[m_dir] * (i - 1);
      int cx = master.second + dx[m_dir] * (i - 1);
      int ny = master.first + dy[m_dir] * i;
      int nx = master.second + dx[m_dir] * i;
      if (ny >= 0 && nx >= 0 && ny < h && nx < w && f[ny][nx] == '#') {
        sy = cy;
        sx = cx;
        break;
      }
    }
    for (int i = 1; i <= 3; i++) {
      if (visited[master.first][master.second][(m_dir + i) % 4][sy][sx]
                 [m_dir]) {
        ac = true;
      }
    }
    if (ac) {
      cout << "He can accomplish his mission." << endl;
      goto end;
    } else {
      bool flag = false;
      REP(i, h) REP(j, w) REP(d, 5) FOR(d1, 1, 4) {
        if (visited[master.first][master.second][(m_dir + d1) % 4][i][j][d]) {
          flag = true;
          break;
        }
      }
      if (flag) {
        cout << "He cannot return to the kitchen." << endl;
      } else {
        cout << "He cannot bring tea to his master." << endl;
      }
    }
  end:;
  }
}