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

#include <algorithm>
#include <cmath>
#include <cstdio>
using namespace std;

int d[5][1000];
int x, y;
int sx, sy, gx, gy;
char c;
int nx[5][1000], ny[5][1000], n[5];
int now, next;

int dis(int ay, int ax, int by, int bx) { return abs(ay - by) + abs(ax - bx); }

int main() {
  while (scanf("%d %d", &x, &y) && (x || y)) {
    for (int i = 0; i < 5; i++)
      n[i] = 0;

    for (int i = 0; i < y; i++) {
      for (int j = 0; j < x; j++) {
        scanf(" %c ", &c);
        if (c != '.') {
          if (c == 'S') {
            sx = j;
            sy = i;
          } else if (c == 'G') {
            gx = j;
            gy = i;
          } else {
            int a = c - '1';
            nx[a][n[a]] = j;
            ny[a][n[a]] = i;
            n[a]++;
          }
        }
      }
    }

    int type = -1, res = 1 << 30;
    for (int i = 0; i < 5; i++) {
      for (int j = 0; j < 5; j++)
        for (int k = 0; k < n[j]; k++)
          d[j][k] = 1 << 30;

      now = i;
      for (int j = 0; j < 5; j++) {
        next = (now + 1) % 5;
        if (j == 0) {
          for (int k = 0; k < n[next]; k++) {
            d[next][k] = min(d[next][k], dis(sy, sx, ny[next][k], nx[next][k]));
          }
        } else if (j == 4) {
          int m = 1 << 30;
          for (int k = 0; k < n[now]; k++) {
            m = min(m, d[now][k] + dis(gy, gx, ny[now][k], nx[now][k]));
          }
          if (m < res) {
            type = i;
            res = m;
          }
        } else {
          for (int k = 0; k < n[now]; k++) {
            for (int l = 0; l < n[next]; l++) {
              d[next][l] =
                  min(d[next][l], d[now][k] + dis(ny[now][k], nx[now][k],
                                                  ny[next][l], nx[next][l]));
            }
          }
        }
        now = next;
      }
    }
    if (type < 0)
      printf("NA\\n");
    else
      printf("%d %d\\n", type + 1, res);
  }
}

Error: MLE

Fixed submission:

#include <cstdio>
#include <map>
#include <queue>
using namespace std;

typedef pair<int, int> P1;
typedef pair<P1, int> P2;

int dp[1000][1000][1 << 5];
int x, y, p;
int sx, sy, gx, gy;
char grid[1000][1000];

int main() {
  while (scanf("%d %d", &x, &y) && (x || y)) {
    for (int i = 0; i < y; i++) {
      for (int j = 0; j < x; j++) {
        scanf(" %c ", &grid[i][j]);
        if (grid[i][j] == 'S') {
          sx = j;
          sy = i;
          grid[i][j] = '.';
        }
        if (grid[i][j] == 'G') {
          gx = j;
          gy = i;
          grid[i][j] = '.';
        }
        for (int k = 0; k < (1 << 5); k++)
          dp[i][j][k] = 1 << 30;
      }
    }

    int type = -1, res = 1 << 30;
    for (int i = 0; i < 5; i++) {
      // printf("---%d---\\n",i);
      dp[sy][sx][1 << i] = 0;
      queue<P2> q;
      q.push(P2(P1(sy, sx), 1 << i));
      while (q.size()) {
        P2 p = q.front();
        q.pop();
        int tx = p.first.second, ty = p.first.first, tt = p.second;
        int dx[] = {0, 1, 0, -1}, dy[] = {-1, 0, 1, 0};

        // printf("%d %d %d\\n",ty,tx,tt);

        for (int i = 0; i < 4; i++) {
          int px = tx + dx[i], py = ty + dy[i], pt = tt;
          if (px < 0 || py < 0 || x <= px || y <= py)
            continue;
          if (grid[py][px] != '.') {
            int t = grid[py][px] - '1';
            if (tt & (1 << ((t + 4) % 5)))
              pt |= (1 << t);
          }
          if (dp[py][px][pt] > dp[ty][tx][tt] + 1) {
            dp[py][px][pt] = dp[ty][tx][tt] + 1;
            q.push(P2(P1(py, px), pt));
          }
        }
      }
      if (dp[gy][gx][(1 << 5) - 1] < res) {
        type = i;
        res = dp[gy][gx][(1 << 5) - 1];
      }
    }
    if (type < 0)
      printf("NA\\n");
    else
      printf("%d %d\\n", type + 1, res);
  }
}