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

#include <algorithm>
#include <bitset>
#include <cctype>
#include <climits>
#include <cmath>
#include <cstdio>
#include <iostream>
#include <list>
#include <map>
#include <queue>
#include <vector>

using namespace std;

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

struct Data {
  short x, y;
  char state;
  int dist;
  Data() {}
  Data(short _x, short _y, int _dist, char _state) {
    x = _x;
    y = _y;
    dist = _dist;
    state = _state;
  }
};

Data data_[5 * 1000 * 1000];

class MockQueue {
public:
  int head, tail;

  void Clear() { head = tail = 0; }

  void Enqueue(const Data &d) { data_[tail++] = d; }

  Data Dequeue() { return data_[head++]; }
};

char fld[1000][1000];
bitset<1000> *isUsed;

inline int GetNext(int n) { return (n == 4) ? 0 : n + 1; }

inline int GetPrev(int n) { return (n == 0) ? 4 : n - 1; }

signed main() {
  int W, H;
  MockQueue q;
  isUsed = new bitset<1000>[5 * 1000];
  while (cin >> W >> H, W || H) {
    int sx, sy, gx, gy;
    for (int i = 0; i < H; i++) {
      for (int j = 0; j < W; j++) {
        scanf(" %c", &fld[i][j]);
        if (fld[i][j] == 'S') {
          sx = j;
          sy = i;
        } else if (fld[i][j] == 'G') {
          gx = j;
          gy = i;
        }
      }
    }

    int mi = INT_MAX / 2, ans;
    for (int i = 0; i < 5; i++) {
      q.Clear();
      Data qf;

      q.Enqueue(Data(sx, sy, 0, i));
      for (int j = 0; j < 5; j++) {
        for (int k = 0; k < H; k++) {
          isUsed[j * H + k].reset();
        }
      }
      isUsed[i * H + sy][sx] = true;
      while (q.head != q.tail) {
        qf = q.Dequeue();
        // printf("%d, %d, %d\\n", qf.x, qf.y, qf.state);
        if (qf.x == gx && qf.y == gy && qf.state == GetPrev(i)) {
          if (mi > qf.dist) {
            mi = qf.dist;
            ans = i;
          }
          break;
        }
        for (int j = 0; j < 4; j++) {
          int nx = qf.x + dx[j];
          int ny = qf.y + dy[j];
          if (nx < 0 || W <= nx || ny < 0 || H <= ny)
            continue;
          int state = qf.state;
          if (isdigit(fld[ny][nx]) && fld[ny][nx] - '1' != i &&
              fld[ny][nx] - '1' == GetNext(state)) {
            state = GetNext(state);
          }
          if (isUsed[state * H + ny][nx])
            continue;
          isUsed[state * H + ny][nx] = true;
          q.Enqueue(Data(nx, ny, qf.dist + 1, state));
        }
      }
    }
    if (mi == INT_MAX / 2)
      puts("NA");
    else
      printf("%d %d\\n", ans + 1, mi);
  }
  return 0;
}

Error: MLE

Fixed submission:

#include <algorithm>
#include <cctype>
#include <climits>
#include <cmath>
#include <cstdio>
#include <iostream>
#include <list>
#include <map>
#include <queue>
#include <vector>

using namespace std;

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

struct Data {
  int x, y, dist, state;
  Data() {}
  Data(int _x, int _y, int _dist, int _state) {
    x = _x;
    y = _y;
    dist = _dist;
    state = _state;
  }
};

Data data_[5 * 1000 * 1000];

class MockQueue {
public:
  int head, tail;

  void Clear() { head = tail = 0; }

  void Enqueue(const Data &d) { data_[tail++] = d; }

  Data Dequeue() { return data_[head++]; }
};

char fld[1000][1000];
bool isUsed[5][1000][1000];

inline int GetNext(int n) { return (n == 4) ? 0 : n + 1; }

inline int GetPrev(int n) { return (n == 0) ? 4 : n - 1; }

signed main() {
  int W, H;
  MockQueue q;
  while (cin >> W >> H, W || H) {
    int sx, sy, gx, gy;
    for (int i = 0; i < H; i++) {
      for (int j = 0; j < W; j++) {
        scanf(" %c", &fld[i][j]);
        if (fld[i][j] == 'S') {
          sx = j;
          sy = i;
        } else if (fld[i][j] == 'G') {
          gx = j;
          gy = i;
        }
      }
    }

    int mi = INT_MAX / 2, ans;
    for (int i = 0; i < 5; i++) {
      q.Clear();
      Data qf;

      q.Enqueue(Data(sx, sy, 0, i));
      fill_n((bool *)isUsed, 5 * 1000 * 1000, false);
      isUsed[i][sy][sx] = true;
      while (q.head != q.tail) {
        qf = q.Dequeue();
        if (qf.x == gx && qf.y == gy && qf.state == GetPrev(i)) {
          if (mi > qf.dist) {
            mi = qf.dist;
            ans = i;
            break;
          }
        }
        for (int j = 0; j < 4; j++) {
          int nx = qf.x + dx[j];
          int ny = qf.y + dy[j];
          if (nx < 0 || W <= nx || ny < 0 || H <= ny)
            continue;
          int state = qf.state;
          if (isdigit(fld[ny][nx]) && fld[ny][nx] - '1' != i &&
              fld[ny][nx] - '1' == GetNext(state)) {
            state = GetNext(state);
          }
          if (isUsed[state][ny][nx])
            continue;
          isUsed[state][ny][nx] = true;
          q.Enqueue(Data(nx, ny, qf.dist + 1, state));
        }
      }
    }
    if (mi == INT_MAX / 2)
      puts("NA");
    else
      printf("%d %d\\n", ans, mi);
  }
  return 0;
}