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

#include <algorithm>
#include <cassert>
#include <climits>
#include <cmath>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <fstream>
#include <functional>
#include <iostream>
#include <list>
#include <map>
#include <queue>
#include <set>
#include <sstream>
#include <stack>
#include <string>
#include <vector>

using namespace std;

#define LOG(...) printf(__VA_ARGS__)
// #define LOG(...)
#define FOR(i, a, b) for (int i = (int)(a); i < (int)(b); ++i)
#define REP(i, n) for (int i = 0; i < (int)(n); ++i)
#define ALL(a) (a).begin(), (a).end()
#define RALL(a) (a).rbegin(), (a).rend()
#define EXIST(s, e) ((s).find(e) != (s).end())
#define SORT(c) sort((c).begin(), (c).end())
#define RSORT(c) sort((c).rbegin(), (c).rend())
#define CLR(a) memset((a), 0, sizeof(a))
#define WRAP(x, y, w, h) (0 <= x && x < w && 0 <= y && y < h)

typedef long long ll;
typedef unsigned long long ull;
typedef vector<bool> vb;
typedef vector<int> vi;
typedef vector<ll> vll;
typedef vector<vb> vvb;
typedef vector<vi> vvi;
typedef vector<vll> vvll;
typedef pair<int, int> pii;
typedef pair<ll, ll> pll;

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

struct UnionFind {
  vector<int> v;
  UnionFind(int n) : v(n) {
    for (int i = 0; i < n; i++)
      v[i] = i;
  }
  int find(int x) { return v[x] == x ? x : v[x] = find(v[x]); }
  void unite(int x, int y) { v[find(x)] = find(y); }
};
bool G[50][50][50][50];
int main() {
  int w, h;
  while (cin >> w >> h, w) {
    vector<string> cell1(h);
    vector<string> cell2(h);
    int slx, sly, srx, sry;
    int glx, gly, grx, gry;
    REP(i, h) {
      cin >> cell1[i] >> cell2[i];
      REP(j, w / 2)
      swap(cell2[i][j], cell2[i][w - 1 - j]);
      REP(j, w) {
        if (cell1[i][j] == 'L') {
          sly = i;
          slx = j;
        }
        if (cell1[i][j] == '%') {
          gly = i;
          glx = j;
        }
        if (cell2[i][j] == 'R') {
          sry = i;
          srx = j;
        }
        if (cell2[i][j] == '%') {
          gry = i;
          grx = j;
        }
      }
    }
    REP(i, 50)
    REP(j, 50)
    REP(k, 50)
    REP(l, 50)
    G[i][j][k][l] = false;
    G[sly][slx][sry][srx] = true;
    // set<pair<pair<char,char>, pair<char, char>>> G;
    // G.insert({ {sly,slx},{sry,srx} });
    queue<pair<pair<char, char>, pair<char, char>>> Q;
    Q.push({{sly, slx}, {sry, srx}});
    // bool G2[50][50][50][50] = { false };
    // G2[gly][glx][gry][grx] = true;
    // set<pair<pair<char, char>, pair<char, char>>> G2;
    // G2.insert({ { gly,glx },{ gry,grx } });
    // queue<pair<pair<char, char>, pair<char, char>>> Q2;
    // Q2.push({ { gly,glx },{ sry,grx } });
    string clear = "No";
    while (!Q.empty()) {
      pair<pair<char, char>, pair<char, char>> q;
      q = Q.front();
      Q.pop();
      if (q.first.first == gly && q.first.second == glx &&
          q.second.first == gry && q.second.second == grx) {
        clear = "Yes";
        goto ANS;
      }
      REP(i, 4) {
        int nly = q.first.first + dy[i];
        int nlx = q.first.second + dx[i];
        int nry = q.second.first + dy[i];
        int nrx = q.second.second + dx[i];
        if (!WRAP(nlx, nly, w, h) || cell1[nly][nlx] == '#') {
          nly = q.first.first;
          nlx = q.first.second;
        }
        if (!WRAP(nrx, nry, w, h) || cell2[nry][nrx] == '#') {
          nry = q.second.first;
          nrx = q.second.second;
        }
        bool b1 = (nly == gly && nlx == glx);
        bool b2 = (nry == gry && nrx == grx);
        if (b1 != b2)
          continue;
        if (!G[nly][nlx][nry][nrx]) {
          G[nly][nlx][nry][nrx] = true;
          Q.push({{nly, nlx}, {nry, nrx}});
        }
      }
    }
  ANS:
    cout << clear << endl;
  }
}

Error: MLE

Fixed submission:

#include <algorithm>
#include <cassert>
#include <climits>
#include <cmath>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <fstream>
#include <functional>
#include <iostream>
#include <list>
#include <map>
#include <queue>
#include <set>
#include <sstream>
#include <stack>
#include <string>
#include <vector>

using namespace std;

#define LOG(...) printf(__VA_ARGS__)
// #define LOG(...)
#define FOR(i, a, b) for (int i = (int)(a); i < (int)(b); ++i)
#define REP(i, n) for (int i = 0; i < (int)(n); ++i)
#define ALL(a) (a).begin(), (a).end()
#define RALL(a) (a).rbegin(), (a).rend()
#define EXIST(s, e) ((s).find(e) != (s).end())
#define SORT(c) sort((c).begin(), (c).end())
#define RSORT(c) sort((c).rbegin(), (c).rend())
#define CLR(a) memset((a), 0, sizeof(a))
#define WRAP(x, y, w, h) (0 <= x && x < w && 0 <= y && y < h)

typedef long long ll;
typedef unsigned long long ull;
typedef vector<bool> vb;
typedef vector<int> vi;
typedef vector<ll> vll;
typedef vector<vb> vvb;
typedef vector<vi> vvi;
typedef vector<vll> vvll;
typedef pair<int, int> pii;
typedef pair<ll, ll> pll;

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

struct UnionFind {
  vector<int> v;
  UnionFind(int n) : v(n) {
    for (int i = 0; i < n; i++)
      v[i] = i;
  }
  int find(int x) { return v[x] == x ? x : v[x] = find(v[x]); }
  void unite(int x, int y) { v[find(x)] = find(y); }
};

int main() {
  int w, h;
  while (cin >> w >> h, w) {
    vector<string> cell1(h);
    vector<string> cell2(h);
    int slx, sly, srx, sry;
    int glx, gly, grx, gry;
    REP(i, h) {
      cin >> cell1[i] >> cell2[i];
      REP(j, w / 2)
      swap(cell2[i][j], cell2[i][w - 1 - j]);
      REP(j, w) {
        if (cell1[i][j] == 'L') {
          sly = i;
          slx = j;
        }
        if (cell1[i][j] == '%') {
          gly = i;
          glx = j;
        }
        if (cell2[i][j] == 'R') {
          sry = i;
          srx = j;
        }
        if (cell2[i][j] == '%') {
          gry = i;
          grx = j;
        }
      }
    }
    set<pair<pair<char, char>, pair<char, char>>> G;
    G.insert({{sly, slx}, {sry, srx}});
    queue<pair<pair<char, char>, pair<char, char>>> Q;
    Q.push({{sly, slx}, {sry, srx}});
    string clear = "No";
    while (!Q.empty()) {
      pair<pair<char, char>, pair<char, char>> q;
      q = Q.front();
      Q.pop();
      if (q.first.first == gly && q.first.second == glx &&
          q.second.first == gry && q.second.first == grx) {
        clear = "Yes";
        goto ANS;
      }
      REP(i, 4) {
        int nly = q.first.first + dy[i];
        int nlx = q.first.second + dx[i];
        int nry = q.second.first + dy[i];
        int nrx = q.second.second + dx[i];
        if (!WRAP(nlx, nly, w, h) || cell1[nly][nlx] == '#') {
          nly = q.first.first;
          nlx = q.first.second;
        }
        if (!WRAP(nrx, nry, w, h) || cell2[nry][nrx] == '#') {
          nry = q.second.first;
          nrx = q.second.second;
        }
        bool b1 = (nly == gly && nlx == glx);
        bool b2 = (nry == gry && nrx == grx);
        if (b1 != b2)
          continue;
        if (G.find({{nly, nlx}, {nry, nrx}}) == G.end()) {
          G.insert({{nly, nlx}, {nry, nrx}});
          Q.push({{nly, nlx}, {nry, nrx}});
        }
      }
    }
  ANS:
    cout << clear << endl;
  }
}