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

#include <cstdio>
#include <deque>
#include <map>

#define rep(i, n) for (int i = 0; i < (n); i++)

using namespace std;

typedef long long ll;

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

int h, w;

struct field {
  char B[10][10];
};

ll hash(const field &F) {
  ll res = 0;
  rep(i, h) rep(j, w) res = res * 1000000007 + F.B[i][j];
  return res;
}

int main() {
  for (; scanf("%d%d", &h, &w), h;) {
    char B0[10][11];
    rep(i, h) scanf("%s", B0[i]);

    int gx, gy;
    rep(i, h) rep(j, w) if (B0[i][j] == 'E') gx = j, gy = i, B0[i][j] = '.';

    field ini;
    rep(i, h) rep(j, w) ini.B[i][j] = B0[i][j];

    int ans = -1;
    map<ll, int> dp;
    dp[hash(ini)] = 0;
    deque<pair<int, field>> Q;
    Q.push_back(make_pair(0, ini));
    while (!Q.empty()) {
      int t = Q.front().first;
      field F = Q.front().second;
      Q.pop_front();

      int x, y;
      rep(i, h) rep(j, w) if (F.B[i][j] == '@') x = j, y = i;

      if (x == gx && y == gy) {
        ans = t;
        break;
      }

      // コンテナを押す
      rep(k, 4) {
        int xx = x + dx[k], yy = y + dy[k];
        if (F.B[yy][xx] == 'c' && (F.B[yy + dy[k]][xx + dx[k]] == '.' ||
                                   F.B[yy + dy[k]][xx + dx[k]] == 'w')) {
          field F2 = F;
          F2.B[yy][xx] = '.';
          while (F.B[yy + dy[k]][xx + dx[k]] == '.' ||
                 F.B[yy + dy[k]][xx + dx[k]] == 'w') {
            yy += dy[k];
            xx += dx[k];
            if (F.B[yy][xx] == 'w')
              break;
          }
          F2.B[yy][xx] = (F2.B[yy][xx] == '.' ? 'c' : '.');
          ll h = hash(F2);
          if (dp.count(h) == 0 || dp[h] > t) {
            dp[h] = t;
            Q.push_front(make_pair(t, F2));
          }
        }
      }

      // 移動する
      rep(k, 4) {
        int xx = x + dx[k], yy = y + dy[k];
        if (F.B[yy][xx] == '.') {
          field F2 = F;
          F2.B[y][x] = '.';
          F2.B[yy][xx] = '@';
          ll h = hash(F2);
          if (dp.count(h) == 0 || dp[h] > t + 1) {
            dp[h] = t + 1;
            Q.push_back(make_pair(t + 1, F2));
          }
        }
      }
    }

    printf("%d\\n", ans);
  }

  return 0;
}

Error: MLE

Fixed submission:

#include <cstdio>
#include <deque>
#include <map>

#define rep(i, n) for (int i = 0; i < (n); i++)

using namespace std;

typedef long long ll;

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

int h, w;

struct field {
  char B[10][10];
  bool operator<(const field &F) const {
    rep(i, h) rep(j, w) if (B[i][j] != F.B[i][j]) return B[i][j] != F.B[i][j];
    return false;
  }
};

int main() {
  for (; scanf("%d%d", &h, &w), h;) {
    char B0[10][11];
    rep(i, h) scanf("%s", B0[i]);

    int gx, gy;
    rep(i, h) rep(j, w) if (B0[i][j] == 'E') gx = j, gy = i, B0[i][j] = '.';

    field ini;
    rep(i, h) rep(j, w) ini.B[i][j] = B0[i][j];

    int ans = -1;
    map<field, int> dp;
    deque<pair<int, field>> Q;
    Q.push_back(make_pair(0, ini));
    while (!Q.empty()) {
      int t = Q.front().first;
      field F = Q.front().second;
      Q.pop_front();

      int x, y;
      rep(i, h) rep(j, w) if (F.B[i][j] == '@') x = j, y = i;

      if (x == gx && y == gy) {
        ans = t;
        break;
      }

      // コンテナを押す
      rep(k, 4) {
        int xx = x + dx[k], yy = y + dy[k];
        if (F.B[yy][xx] == 'c' && (F.B[yy + dy[k]][xx + dx[k]] == '.' ||
                                   F.B[yy + dy[k]][xx + dx[k]] == 'w')) {
          field F2 = F;
          F2.B[yy][xx] = '.';
          while (F.B[yy + dy[k]][xx + dx[k]] == '.' ||
                 F.B[yy + dy[k]][xx + dx[k]] == 'w') {
            yy += dy[k];
            xx += dx[k];
          }
          F2.B[yy][xx] = (F2.B[yy][xx] == '.' ? 'c' : '.');
          if (dp.count(F2) == 0 || dp[F2] > t) {
            dp[F2] = t;
            Q.push_front(make_pair(t, F2));
          }
        }
      }

      // 移動する
      rep(k, 4) {
        int xx = x + dx[k], yy = y + dy[k];
        if (F.B[yy][xx] == '.') {
          field F2 = F;
          F2.B[y][x] = '.';
          F2.B[yy][xx] = '@';
          if (dp.count(F2) == 0 || dp[F2] > t + 1) {
            dp[F2] = t + 1;
            Q.push_back(make_pair(t + 1, F2));
          }
        }
      }
    }

    printf("%d\\n", ans);
  }

  return 0;
}