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

#include <algorithm>
#include <cassert>
#include <cmath>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <iostream>
#include <map>
#include <numeric>
#include <queue>
#include <set>
#include <sstream>
#include <vector>

#define rep(i, n) for (int i = 0; i < n; i++)
#define all(c) (c).begin(), (c).end()
#define mp make_pair
#define pb push_back
#define rp(i, c) rep(i, (c).size())
#define fr(i, c)                                                               \\
  for (__typeof((c).begin()) i = (c).begin(); i != (c).end(); i++)
#define dbg(x) cerr << #x << " = " << (x) << endl

using namespace std;

typedef long long ll;
typedef vector<int> vi;
typedef pair<int, int> pi;
const int inf = 1 << 28;
const double INF = 1e12, EPS = 1e-9;

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

int h, w, ey, ex;
char room[10][11];
struct S {
  int y, x, nc, np;
  pi c[3], p[3];
  bool operator<(const S &r) const {
    if (y != r.y)
      return y < r.y;
    if (x != r.x)
      return x < r.x;
    if (nc != r.nc)
      return nc < r.nc;
    rep(i, nc) if (c[i] != r.c[i]) return c[i] < r.c[i];
    if (np != r.np)
      return np < r.np;
    rep(i, np) if (p[i] != r.p[i]) return p[i] < r.p[i];
    return 0;
  }
};
int solve(S s) {
  set<S> V;
  V.insert(s);
  deque<pair<int, S>> Q;
  Q.pb(mp(0, s));

  while (!Q.empty()) {
    int cc = Q.front().first;
    s = Q.front().second;
    Q.pop_front();

    if (s.y == ey && s.x == ex)
      return cc;

    // move
    rep(d, 4) {
      S ns = s;
      ns.y = s.y + dy[d], ns.x = s.x + dx[d];
      if (room[ns.y][ns.x] == '#')
        continue;
      rep(i, s.nc) if (mp(ns.y, ns.x) == s.c[i]) goto FAIL;
      rep(i, s.np) if (mp(ns.y, ns.x) == s.p[i]) goto FAIL;

      if (V.count(ns))
        continue;
      V.insert(ns);
      Q.pb(mp(cc + 1, ns));
    FAIL:;
    }
    // push
    rep(d, 4) {
      S ns = s;
      int ny = s.y + dy[d], nx = s.x + dx[d], c = 0;
      for (; c < s.nc; c++)
        if (mp(ny, nx) == s.c[c])
          break;
      if (c == s.nc)
        continue;

      int cy = ny, cx = nx, p = -1;
      while (1) {
        ny += dy[d];
        nx += dx[d];
        if (room[ny][nx] == '#')
          break;
        rep(i, s.nc) if (mp(ny, nx) == s.c[i]) goto END;
        rep(i, s.np) if (mp(ny, nx) == s.p[i]) {
          p = i;
          goto END;
        }
        cy = ny;
        cx = nx;
      }
    END:
      if (p != -1) {
        for (int i = c; i < s.nc - 1; i++)
          ns.c[i] = ns.c[i + 1];
        for (int i = p; i < s.np - 1; i++)
          ns.p[i] = ns.p[i + 1];
        ns.nc--;
        ns.np--;

        if (!V.count(ns))
          V.insert(ns), Q.push_front(mp(cc, ns));
      } else if (mp(cy, cx) != s.c[c]) {
        ns.c[c] = mp(cy, cx);
        if (!V.count(ns))
          V.insert(ns), Q.push_front(mp(cc, ns));
      }
    }
  }
  return -1;
}
int main() {
  while (scanf("%d%d", &h, &w), h) {
    S s;
    s.nc = s.np = 0;
    rep(i, h) {
      scanf("%s", room[i]);
      rep(j, w) {
        char &c = room[i][j];
        if (c == 'c')
          s.c[s.nc++] = mp(i, j), c = '.';
        else if (c == 'w')
          s.p[s.np++] = mp(i, j), c = '.';
        else if (c == '@')
          s.y = i, s.x = j, c = '.';
        else if (c == 'E')
          ey = i, ex = j, c = '.';
      }
    }
    printf("%d\\n", solve(s));
  }
  return 0;
}

Error: MLE

Fixed submission:

#include <algorithm>
#include <iostream>
#include <queue>
#include <set>
using namespace std;
typedef pair<int, int> pi;
#define rep(i, n) for (int i = 0; i < n; i++)
#define mp make_pair

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

int w, h, gy, gx;
char rm[12][13];
struct S {
  int nc, np;
  pi pp[3], cp[3];
  int y, x;
  bool operator<(const S &r) const {
    rep(i, min(nc, r.nc)) if (cp[i] < r.cp[i]) return 1;
    if (nc != r.nc)
      return nc < r.nc;
    rep(i, min(np, r.np)) if (pp[i] < r.pp[i]) return 1;
    if (np != r.np)
      return np < r.np;
    return mp(y, x) < mp(r.y, r.x);
  }
};

int main() {
  while (cin >> h >> w, w) {
    S st, nxt;
    st.nc = st.np = 0;

    rep(i, h) {
      cin >> rm[i];
      rep(j, w) {
        if (rm[i][j] == '@')
          st.y = i, st.x = j;
        else if (rm[i][j] == 'E')
          gy = i, gx = j;
        else if (rm[i][j] == 'c')
          st.cp[st.nc++] = mp(i, j);
        else if (rm[i][j] == 'w')
          st.pp[st.np++] = mp(i, j);

        if (rm[i][j] != '#')
          rm[i][j] = '.';
      }
    }

    priority_queue<pair<int, S>> Q;
    Q.push(mp(0, st));
    set<S> V;
    V.insert(st);

    int ans = -1;
    while (!Q.empty()) {
      st = Q.top().second;
      int cc = Q.top().first;
      Q.pop();

      if (st.y == gy && st.x == gx) {
        ans = -cc;
        break;
      }

      rep(d, 4) {
        int ny = st.y + dy[d], nx = st.x + dx[d];
        if (rm[ny][nx] == '#')
          continue;
        rep(i, st.np) if (st.pp[i] == mp(ny, nx)) goto NEXT;

        // panel move
        rep(i, st.nc) if (st.cp[i] == mp(ny, nx)) {
          int py = ny + dy[d], px = nx + dx[d];
          nxt = st;
          while (rm[py][px] != '#') {
            rep(j, st.nc) if (i != j && st.cp[j] == mp(py, px)) {
              nxt.cp[i] = mp(py - dy[d], px - dx[d]);
              sort(nxt.cp, nxt.cp + nxt.nc);
              goto OUT;
            }
            rep(j, st.np) if (st.pp[j] == mp(py, px)) {
              // panel erase
              for (int k = j + 1; k < st.np; k++)
                nxt.pp[k - 1] = nxt.pp[k];
              nxt.np--;
              sort(nxt.pp, nxt.pp + nxt.np);
              // contener erase
              for (int k = i + 1; k < st.nc; k++)
                nxt.cp[k - 1] = nxt.cp[k];
              nxt.nc--;
              sort(nxt.cp, nxt.cp + nxt.nc);

              goto OUT;
            }

            py += dy[d], px += dx[d];
          }
        OUT:
          if (!V.count(nxt))
            V.insert(nxt), Q.push(mp(cc, nxt));

          goto NEXT;
        }
        // Dr move
        nxt = st;
        nxt.y = ny, nxt.x = nx;
        if (!V.count(nxt))
          V.insert(nxt), Q.push(mp(cc - 1, nxt));

      NEXT:;
      }
    }
    cout << ans << endl;
  }
  return 0;
}