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

#include <bits/stdc++.h>
using namespace std;

using P = pair<int, int>;
using S = pair<P, P>;

using vi = vector<int>;
using vvi = vector<vi>;
using vvvi = vector<vvi>;
using vvvvi = vector<vvvi>;

int main() {
  int w, h;
  while (cin >> w >> h, h) {
    vector<string> l(h + 2, ""), r(h + 2, "");
    for (int i = 0; i < w + 2; i++) {
      l[0] += "#";
      l[h + 1] += "#";
      r[0] += "#";
      r[h + 1] += "#";
    }
    for (int i = 0; i < h; i++) {
      cin >> l[i + 1] >> r[i + 1];
      l[i + 1] = "#" + l[i + 1] + "#";
      r[i + 1] = "#" + r[i + 1] + "#";
    }
    h += 2;
    w += 2;

    int lh, lw;
    int rh, rw;
    for (int i = 0; i < h; i++) {
      for (int j = 0; j < w; j++) {
        if (l[i][j] == 'L') {
          lh = i, lw = j;
        }
        if (r[i][j] == 'R') {
          rh = i, rw = j;
        }
      }
    }

    P iniL = {lh, lw}, iniR = {rh, rw};
    S ini = {iniL, iniR};

    vvvvi dp(h, vvvi(w, vvi(h, vi(w, false))));
    queue<S> que;

    que.push(ini);
    bool isok = false;

    int dh[] = {0, 1, 0, -1};
    int dw[] = {1, 0, -1, 0};
    while (!que.empty()) {
      auto state = que.front();
      que.pop();
      P lp = state.first, rp = state.second;
      if (dp[lp.first][lp.second][rp.first][rp.second])
        continue;
      dp[lp.first][lp.second][rp.first][rp.second] = true;
      int isL = (l[lp.first][lp.second] == '%');
      int isR = (r[rp.first][rp.second] == '%');
      if (isL + isR == 2) {
        isok = true;
        break;
      }
      if (isL + isR == 1)
        continue;

      for (int i = 0; i < 4; i++) {
        P toL = {lp.first + dh[i], lp.second + dw[i]};
        if (l[toL.first][toL.second] == '#')
          toL = lp;
        P toR = {rp.first + dh[i], rp.second - dw[i]};
        if (r[toR.first][toR.second] == '#')
          toR = rp;
        que.push({toL, toR});
      }
    }

    cout << (isok ? "Yes" : "No") << endl;
  }
  return 0;
}


Error: MLE

Fixed submission:

#include <bits/stdc++.h>
using namespace std;

int dh[] = {1, 0, -1, 0};
int dw[] = {0, 1, 0, -1};
int w, h;
bool isrange(int x, int y) { return 0 <= x && x < h && 0 <= y && y < w; };
int main() {

  while (cin >> w >> h, w) {
    vector<string> rl(h), rr(h);
    for (int i = 0; i < h; i++) {
      cin >> rl[i] >> rr[i];
    }
    pair<int, int> lp;
    pair<int, int> rp;
    for (int i = 0; i < h; i++) {
      for (int j = 0; j < w; j++) {
        if (rl[i][j] == 'L')
          lp = {i, j};
        if (rr[i][j] == 'R')
          rp = {i, j};
      }
    }
    stack<pair<pair<int, int>, pair<int, int>>> que;
    que.push({lp, rp});
    set<pair<pair<int, int>, pair<int, int>>> dp;
    dp.insert({lp, rp});

    auto move = [&rl, &rr](int x, int dx, int y, int dy, bool isr) {
      if (!isrange(x + dx, y + dy)) {
        return make_pair(min(max(x + dx, 0), h - 1),
                         min(max(y + dy, 0), w - 1));
      }
      if (isr) {
        if (rr[x + dx][y + dy] == '#')
          return make_pair(x, y);
        else
          return make_pair(x + dx, y + dy);
      } else {
        if (rl[x + dx][y + dy] == '#')
          return make_pair(x, y);
        else
          return make_pair(x + dx, y + dy);
      }
    };
    while (!que.empty()) {
      auto p = que.top();
      que.pop();
      for (int i = 0; i < 4; i++) {
        auto tol = move(p.first.first, dh[i], p.first.second, dw[i], 0);
        auto tor =
            move(p.second.first, dh[i], p.second.second, dw[(i + 2) % 2], 1);
        pair<pair<int, int>, pair<int, int>> tost = {tol, tor};
        if (dp.count(tost))
          continue;
        dp.insert(tost);
        que.push(tost);
      }
    }
    pair<int, int> obl;
    pair<int, int> obr;
    for (int i = 0; i < h; i++) {
      for (int j = 0; j < w; j++) {
        if (rl[i][j] == '%')
          obl = {i, j};
        if (rr[i][j] == '%')
          obr = {i, j};
      }
    }
    if (dp.count({obl, obr}))
      cout << "Yes" << endl;
    else
      cout << "No" << endl;
  }

  return 0;
}