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


#include <bits/stdc++.h>
using namespace std;
using ll = long long;
using vi = vector<int>;
using vvi = vector<vi>;
using vs = vector<string>;
using msi = map<string, int>;
using mii = map<int, int>;
using psi = pair<string, int>;
using pii = pair<int, int>;
using vlai = valarray<int>;
#define rep(i, n) for (int i = 0; i < n; i++)
#define range(i, s, n) for (int i = s; i < n; i++)
#define all(a) a.begin(), a.end()
#define rall(a) a.rbegin(), a.rend()
#define fs first
#define sc second
#define pb push_back
#define eb emplace_back
#define mp make_pair
#define INF 1e9
#define EPS 1e-9
#define MOD (1e9 + 7)
void get() {}
template <class H, class... T> void get(H &h, T &...t) {
  cin >> h;
  get(t...);
}
template <class T> void geti(T &a) {
  for (auto &_ : a)
    cin >> _;
}
template <class T> void getii(T &a) {
  for (auto &_ : a)
    geti(_);
}
void put(string d) {}
template <class H, class... T> void put(string d, H &h, T &...t) {
  cout << h;
  if (sizeof...(t))
    cout << d;
  put(d, t...);
}
template <class T> void puti(T &a, string d = " ") {
  bool f = 1;
  for (auto &_ : a)
    cout << (exchange(f, 0) ? "" : d) << _;
  cout << endl;
}
template <class T> void putii(T &a, string d = " ") {
  for (auto &_ : a)
    puti(_, d);
}
#define dcl(...)                                                               \\
  ll __VA_ARGS__;                                                              \\
  get(__VA_ARGS__)
#define dclt(t, ...)                                                           \\
  t __VA_ARGS__;                                                               \\
  get(__VA_ARGS__)

#define fs first
#define sc second

int main() {
  int w, h;
  while (cin >> w >> h, w) {
    vector<vvi> f(2, vvi(h + 2, vi(w + 2, 1)));
    pair<pii, pii> curr;
    pair<pii, pii> stat;
    for (int i = 1; i <= h; i++) {
      rep(p, 2) {
        for (int j = 1; j <= w; j++) {
          char c;
          cin >> c;
          if (c == '.') {
            f[p][i][j] = 0;
          } else if (c == '%') {
            f[p][i][j] = 0;
            if (p == 0) {
              stat.first = {i, j};
            } else {
              stat.second = {i, w + 1 - j};
            }
          } else if (c == 'L') {
            f[p][i][j] = 0;
            curr.first = {i, j};
          } else if (c == 'R') {
            f[p][i][j] = 0;
            curr.second = {i, w + 1 - j};
          }
        }
      }
      reverse(all(f[1][i]));
    }
    // putii(f[0],"");
    // cout<<endl;
    // putii(f[1],"");
    // cout<<"======="<<endl;

    /*幅優先
            ・どちらか片方だけ動き、動いた先がゴールでない場合
            ・両方動き、かつ少なくともどちらかがそのマスを訪れたことがない場合
            だけ、探索する
    */
    set<pair<pii, pii>> isVisited;

    queue<pair<pii, pii>> que;
    que.push(curr);
    int y[] = {-1, 0, 1, 0};
    int x[] = {0, 1, 0, -1};
    auto step = [f](pii &pos, int lr, int y, int x) {
      if (f[lr][pos.fs + y][pos.sc + x] != 1) {
        pos.fs += y;
        pos.sc += x;
        return true;
      }
      return false;
    };
    bool ok = false;
    while (!que.empty()) {
      auto c = que.front();
      que.pop();
      // cout<<c[0][0]<<","<<c[0][1]<<"  "<<c[1][0]<<","<<c[1][1]<<endl;
      if (isVisited.find(c) != isVisited.end()) {
        continue;
      }
      isVisited.insert(c);
      rep(v, 4) {
        auto next = c;
        bool l = step(next.fs, 0, y[v], x[v]);
        bool r = step(next.sc, 1, y[v], x[v]);
        if (next == stat) {
          ok = true;
          goto fin;
        }

        if (isVisited.find(next) == isVisited.end()) {
          if ((!l and r and next.sc != stat.sc) or
              (l and !r and next.fs != stat.fs) or
              (l and r and (next.fs != stat.fs and next.sc != stat.sc))) {
            // cout<<" o "<<next[0][0]<<","<<next[0][1]<<"
            // "<<next[1][0]<<","<<next[1][1]<<endl;
            que.push(next);
          } else {
            // cout<<" x "<<next[0][0]<<","<<next[0][1]<<"
            // "<<next[1][0]<<","<<next[1][1]<<endl;
          }
        }
      }
    }
  fin:;
    if (ok) {
      cout << "Yes" << endl;
    } else {
      cout << "No" << endl;
    }
  }
  return 0;
}


Error: MLE

Fixed submission:


#include <bits/stdc++.h>
using namespace std;
using ll = long long;
using vi = vector<int>;
using vvi = vector<vi>;
using vs = vector<string>;
using msi = map<string, int>;
using mii = map<int, int>;
using psi = pair<string, int>;
using pii = pair<int, int>;
using vlai = valarray<int>;
#define rep(i, n) for (int i = 0; i < n; i++)
#define range(i, s, n) for (int i = s; i < n; i++)
#define all(a) a.begin(), a.end()
#define rall(a) a.rbegin(), a.rend()
#define fs first
#define sc second
#define pb push_back
#define eb emplace_back
#define mp make_pair
#define INF 1e9
#define EPS 1e-9
#define MOD (1e9 + 7)
void get() {}
template <class H, class... T> void get(H &h, T &...t) {
  cin >> h;
  get(t...);
}
template <class T> void geti(T &a) {
  for (auto &_ : a)
    cin >> _;
}
template <class T> void getii(T &a) {
  for (auto &_ : a)
    geti(_);
}
void put(string d) {}
template <class H, class... T> void put(string d, H &h, T &...t) {
  cout << h;
  if (sizeof...(t))
    cout << d;
  put(d, t...);
}
template <class T> void puti(T &a, string d = " ") {
  bool f = 1;
  for (auto &_ : a)
    cout << (exchange(f, 0) ? "" : d) << _;
  cout << endl;
}
template <class T> void putii(T &a, string d = " ") {
  for (auto &_ : a)
    puti(_, d);
}
#define dcl(...)                                                               \\
  ll __VA_ARGS__;                                                              \\
  get(__VA_ARGS__)
#define dclt(t, ...)                                                           \\
  t __VA_ARGS__;                                                               \\
  get(__VA_ARGS__)

int main() {
  int w, h;
  while (cin >> w >> h, w) {
    vector<vvi> f(2, vvi(h + 2, vi(w + 2, 1)));
    vvi curr(2, vi(2));
    vvi stat(2, vi(2));
    for (int i = 1; i <= h; i++) {
      rep(p, 2) {
        for (int j = 1; j <= w; j++) {
          char c;
          cin >> c;
          if (c == '.') {
            f[p][i][j] = 0;
          } else if (c == '%') {
            f[p][i][j] = 0;
            stat[p] = {i, j};
          } else if (c == 'L') {
            f[p][i][j] = 0;
            curr[0] = {i, j};
          } else if (c == 'R') {
            f[p][i][j] = 0;
            curr[1] = {i, w + 1 - j};
          }
        }
      }
      reverse(all(f[1][i]));
    }
    stat[1][1] = w + 1 - stat[1][1];
    // putii(f[0],"");
    // cout<<endl;
    // putii(f[1],"");
    // cout<<"======="<<endl;

    /*幅優先
            ・どちらか片方だけ動き、動いた先がゴールでない場合
            ・両方動き、かつ少なくともどちらかがそのマスを訪れたことがない場合
            だけ、探索する
    */
    set<vvi> isVisited;
    // isVisited.insert(curr);

    queue<vvi> que;
    que.push(curr);
    int y[] = {-1, 0, 1, 0};
    int x[] = {0, 1, 0, -1};
    auto step = [f](vi &pos, int lr, int y, int x) {
      if (f[lr][pos[0] + y][pos[1] + x] != 1) {
        pos[0] += y;
        pos[1] += x;
        return true;
      }
      return false;
    };
    bool ok = false;
    while (!que.empty()) {
      auto c = que.front();
      que.pop();
      // cout<<c[0][0]<<","<<c[0][1]<<"  "<<c[1][0]<<","<<c[1][1]<<endl;
      if (isVisited.find(c) != isVisited.end()) {
        continue;
      }
      isVisited.insert(c);
      rep(v, 4) {
        auto next = c;
        bool l = step(next[0], 0, y[v], x[v]);
        bool r = step(next[1], 1, y[v], x[v]);
        if (next == stat) {
          ok = true;
          goto fin;
        }

        if (isVisited.find(next) == isVisited.end()) {
          if ((!l and r and next[1] != stat[1]) or
              (l and !r and next[0] != stat[0]) or
              (l and r and !(next[0] != stat[0] xor next[1] != stat[1]))) {
            // cout<<" o "<<next[0][0]<<","<<next[0][1]<<"
            // "<<next[1][0]<<","<<next[1][1]<<endl;
            que.push(next);
          } else {
            // cout<<" x "<<next[0][0]<<","<<next[0][1]<<"
            // "<<next[1][0]<<","<<next[1][1]<<endl;
          }
        }
      }
    }
  fin:;
    if (ok) {
      cout << "Yes" << endl;
    } else {
      cout << "No" << endl;
    }
  }
  return 0;
}