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 <queue>
#include <set>
#include <sstream>
#include <stack>
#include <string>
#include <vector>

using namespace std;

#define FOR(i, k, n) for (int i = (k); i < (int)(n); ++i)
#define REP(i, n) FOR(i, 0, n)
#define FORIT(i, c)                                                            \\
  for (__typeof((c).begin()) i = (c).begin(); i != (c).end(); ++i)

template <class T> void debug(T begin, T end) {
  for (T i = begin; i != end; ++i)
    cerr << *i << " ";
  cerr << endl;
}
inline bool valid(int x, int y, int W, int H) {
  return (x >= 0 && y >= 0 && x < W && y < H);
}

typedef long long ll;
const int INF = 100000000;
const double EPS = 1e-8;
const int MOD = 1000000007;
int dx[8] = {1, 0, -1, 0, 1, -1, -1, 1};
int dy[8] = {0, 1, 0, -1, 1, 1, -1, -1};
struct S {
  int x, y;
  int cx[3];
  int cy[3];
  int SW;
  int cost;
  S() {
    SW = 0;
    cx[0] = cx[1] = cx[2] = 10;
    cy[0] = cy[1] = cy[2] = 10;
    cost = 0;
  }
  bool operator<(const S &s) const {
    if (x != s.x)
      return x < s.x;
    if (y != s.y)
      return y < s.y;
    REP(i, 3) if (cx[i] != s.cx[i]) return cx[i] < s.cx[i];
    REP(i, 3) if (cy[i] != s.cy[i]) return cy[i] < s.cy[i];
    return SW < s.SW;
  }
};
bool get(S &s, bool cost[10][10][11][11][11][11][11][11]) {
  return cost[s.y][s.x][s.cy[0]][s.cx[0]][s.cy[1]][s.cx[1]][s.cy[2]][s.cx[2]];
}
void set_x(S &s, bool x, bool cost[10][10][11][11][11][11][11][11]) {
  cost[s.y][s.x][s.cy[0]][s.cx[0]][s.cy[1]][s.cx[1]][s.cy[2]][s.cx[2]] = x;
}
void print(S &s) {
  printf("x = %d y = %d SW = %d cost = %d c = (%d, %d) (%d, %d) (%d, %d)\\n",
         s.x, s.y, s.SW, s.cost, s.cx[0], s.cy[0], s.cx[1], s.cy[1], s.cx[2],
         s.cy[2]);
}
int main() {
  int H, W;
  while (cin >> H >> W && H) {
    vector<string> grid(H);
    REP(i, H) cin >> grid[i];
    int WC = 0;
    int CC = 0;
    int wx[3], wy[3];
    S start;
    REP(y, H) REP(x, W) {
      if (grid[y][x] == '@') {
        start.x = x, start.y = y;
      }
      if (grid[y][x] == 'w') {
        wx[WC] = x, wy[WC] = y;
        start.SW |= 1 << WC;
        WC++;
      }
      if (grid[y][x] == 'c') {
        start.cx[CC] = x;
        start.cy[CC] = y;
        CC++;
      }
    }
    // static bool cost[10][10][11][11][11][11][11][11] = {};
    // memset(cost, 0, sizeof(cost));
    set<S> setS;
    deque<S> que;
    que.push_back(start);
    // set_x(start, 1, cost);
    setS.insert(start);
    bool NG = true;
    while (!que.empty()) {
      S s = que.front();
      que.pop_front();
      // print(s);
      if (grid[s.y][s.x] == 'E') {
        cout << s.cost << endl;
        NG = false;
        break;
      }
      REP(r, 4) {
        int nx = s.x + dx[r];
        int ny = s.y + dy[r];
        if (!valid(nx, ny, W, H))
          continue;
        S next = s;
        bool move = true;
        REP(i, CC) {
          if (nx == s.cx[i] && ny == s.cy[i]) {
            move = false;
            // container move
            int xx = nx, yy = ny;
            while (true) {
              xx += dx[r];
              yy += dy[r];
              if (grid[yy][xx] == '#') {
                xx -= dx[r];
                yy -= dy[r];
                goto C1;
              }
              REP(j, CC) if (i != j && s.cx[j] == xx && s.cy[j] == yy) {
                xx -= dx[r];
                yy -= dy[r];
                goto C1;
              }
              REP(i, WC) if (s.SW >> i & 1 && wx[i] == xx && wy[i] == yy) {
                next.SW ^= 1 << i;
                xx = 10;
                yy = 10;
                goto C1;
              }
            }
          C1:
            next.cx[i] = xx, next.cy[i] = yy;
            // if(!get(next, cost)){
            if (!setS.count(next)) {
              // set_x(next, true, cost);
              setS.insert(next);
              que.push_front(next);
            }
          }
        }
        REP(i, WC)
        if (s.SW >> i & 1 && wx[i] == nx && wy[i] == ny) move = false;
        if (!move || grid[ny][nx] == '#')
          continue;
        next.x = nx, next.y = ny;
        // if(!get(next, cost)){
        if (!setS.count(next)) {
          next.cost += 1;
          // set_x(next, true, cost);
          setS.insert(next);
          que.push_back(next);
        }
      }
    }
    if (NG)
      cout << -1 << endl;
  }
  return 0;
}

Error: MLE

Fixed submission:

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

using namespace std;

#define FOR(i, k, n) for (int i = (k); i < (int)(n); ++i)
#define REP(i, n) FOR(i, 0, n)
#define FORIT(i, c)                                                            \\
  for (__typeof((c).begin()) i = (c).begin(); i != (c).end(); ++i)

template <class T> void debug(T begin, T end) {
  for (T i = begin; i != end; ++i)
    cerr << *i << " ";
  cerr << endl;
}
inline bool valid(int x, int y, int W, int H) {
  return (x >= 0 && y >= 0 && x < W && y < H);
}

typedef long long ll;
const int INF = 100000000;
const double EPS = 1e-8;
const int MOD = 1000000007;
int dx[8] = {1, 0, -1, 0, 1, -1, -1, 1};
int dy[8] = {0, 1, 0, -1, 1, 1, -1, -1};
struct S {
  int x, y;
  int cx[3];
  int cy[3];
  int SW;
  int cost;
  S() {
    SW = 0;
    cx[0] = cx[1] = cx[2] = 10;
    cy[0] = cy[1] = cy[2] = 10;
    cost = 0;
  }
};
bool get(S &s, bool cost[10][10][11][11][11][11][11][11]) {
  return cost[s.y][s.x][s.cy[0]][s.cx[0]][s.cy[1]][s.cx[1]][s.cy[2]][s.cx[2]];
}
void set_x(S &s, bool x, bool cost[10][10][11][11][11][11][11][11]) {
  cost[s.y][s.x][s.cy[0]][s.cx[0]][s.cy[1]][s.cx[1]][s.cy[2]][s.cx[2]] = x;
}
void print(S &s) {
  printf("x = %d y = %d SW = %d cost = %d c = (%d, %d) (%d, %d) (%d, %d)\\n",
         s.x, s.y, s.SW, s.cost, s.cx[0], s.cy[0], s.cx[1], s.cy[1], s.cx[2],
         s.cy[2]);
}
int main() {
  int H, W;
  while (cin >> H >> W && H) {
    vector<string> grid(H);
    REP(i, H) cin >> grid[i];
    int WC = 0;
    int CC = 0;
    int wx[3], wy[3];
    S start;
    REP(y, H) REP(x, W) {
      if (grid[y][x] == '@') {
        start.x = x, start.y = y;
      }
      if (grid[y][x] == 'w') {
        wx[WC] = x, wy[WC] = y;
        start.SW |= 1 << WC;
        WC++;
      }
      if (grid[y][x] == 'c') {
        start.cx[CC] = x;
        start.cy[CC] = y;
        CC++;
      }
    }
    static bool cost[10][10][11][11][11][11][11][11] = {};
    memset(cost, 0, sizeof(cost));
    deque<S> que;
    que.push_back(start);
    set_x(start, 1, cost);
    bool NG = true;
    while (!que.empty()) {
      S s = que.front();
      que.pop_front();
      // print(s);
      if (grid[s.y][s.x] == 'E') {
        cout << s.cost << endl;
        NG = false;
        break;
      }
      REP(r, 4) {
        int nx = s.x + dx[r];
        int ny = s.y + dy[r];
        if (!valid(nx, ny, W, H))
          continue;
        S next = s;
        bool move = true;
        REP(i, 3) {
          if (nx == s.cx[i] && ny == s.cy[i]) {
            move = false;
            // container move
            int xx = nx, yy = ny;
            while (true) {
              xx += dx[r];
              yy += dy[r];
              if (grid[yy][xx] == '#') {
                xx -= dx[r];
                yy -= dy[r];
                break;
              }
              REP(i, 3) if (s.SW >> i & 1 && wx[i] == xx && wy[i] == yy) {
                next.SW ^= 1 << i;
                xx = 10;
                yy = 10;
              }
              if (!valid(xx, yy, W, H))
                break;
            }
            next.cx[i] = xx, next.cy[i] = yy;
            if (!get(next, cost)) {
              set_x(next, true, cost);
              que.push_front(next);
            }
          }
        }
        REP(i, 3) if (s.SW >> i & 1 && wx[i] == nx && wy[i] == ny) move = false;
        if (!move || grid[ny][nx] == '#')
          continue;
        next.x = nx, next.y = ny;
        if (!get(next, cost)) {
          next.cost += 1;
          set_x(next, true, cost);
          que.push_back(next);
        }
      }
    }
    if (NG)
      cout << -1 << endl;
  }
  return 0;
}