Problem p00860 (C++)

Buggy submission (status: Memory Limit Exceeded):
#include <cctype>
#include <cstdio>
#include <cstring>
#include <iostream>
#include <queue>
#include <string>
using namespace std;

char f[16][16];
int fx, fy, N;
int dx[] = {0, 0, -1, 1, 0};
int dy[] = {0, -1, 0, 0, 1};

class Ghost {
public:
  int x[3], y[3], c;
  bool r;

  Ghost(int *i, int *j, int c, bool r) : r(r), c(c) {
    for (int k = 0; k < 3; k++) {
      x[k] = i[k];
      y[k] = j[k];
    }
  }
};

bool move(int x, int y, int p) {
  if (p >= N)
    return true;
  if (x < 0 || y < 0 || x >= fx || y >= fy)
    return false;
  if (f[x][y] == '#')
    return false;

  return true;
}

bool crash(int *x, int *y, int *gx, int *gy, int p) {
  if (p < N)
    return false;
  for (int i = 0; i < p; i++)
    for (int j = i + 1; j < p; j++) {
      if (x[i] == x[j] && y[i] == y[j])
        return true;
      if (x[i] == gx[j] && y[i] == gy[j] && gx[i] == x[j] && gy[i] == y[j])
        return true;
    }
  return false;
}

short h[256][256][256][2];

int main() {
  while (scanf("%d%d%d", &fx, &fy, &N), (fx || fy || N)) {
    int sx[3] = {0}, sy[3] = {0}, gx[3] = {0}, gy[3] = {0};
    memset(h, 0, sizeof(h));

    string s;

    getchar();
    for (int i = 0; i < fy; i++) {
      getline(cin, s);
      for (int j = 0; j < fx; j++) {
        if (islower(s[j])) {
          sx[s[j] - 'a'] = j;
          sy[s[j] - 'a'] = i;
        }
        if (isupper(s[j])) {
          gx[s[j] - 'A'] = j;
          gy[s[j] - 'A'] = i;
        }

        f[j][i] = s[j];
      }
    }

    queue<Ghost> q;
    q.push(Ghost(sx, sy, 1, 0));
    q.push(Ghost(gx, gy, 1, 1));

    int th[3];
    for (int l = 0; l < 3; l++) {
      th[l] = (sx[l] << 4) + sy[l];
    }
    h[th[0]][th[1]][th[2]][0] = 1;
    for (int l = 0; l < 3; l++) {
      th[l] = (gx[l] << 4) + gy[l];
    }
    h[th[0]][th[1]][th[2]][1] = 1;

    while (!q.empty()) {
      Ghost g = q.front();
      q.pop();

      int th[3];

      for (int l = 0; l < 3; l++) {
        th[l] = (g.x[l] << 4) + g.y[l];
      }

      if (h[th[0]][th[1]][th[2]][!g.r]) {
        printf("%d\n", g.c + h[th[0]][th[1]][th[2]][!g.r] - 1);
        break;
      }

      int tx[3], ty[3];
      for (int i = 0; i < 3; i++) {
        tx[i] = g.x[i];
        ty[i] = g.y[i];
      }

      for (int i = 0; i < 5; i++) {
        tx[0] = g.x[0] + dx[i], ty[0] = g.y[0] + dy[i];
        if (!move(tx[0], ty[0], 0)) {
          tx[0] = g.x[0];
          ty[0] = g.y[0];
          continue;
        }

        for (int j = 0; j < (N > 1 ? 5 : 1); j++) {
          tx[1] = g.x[1] + dx[j], ty[1] = g.y[1] + dy[j];
          if (N >= 2) {
            if (!move(tx[1], ty[1], 1) || (crash(tx, ty, g.x, g.y, 2))) {
              tx[1] = g.x[1];
              ty[1] = g.y[1];
              continue;
            }
          }

          for (int k = 0; k < (N > 2 ? 5 : 1); k++) {
            tx[2] = g.x[2] + dx[k], ty[2] = g.y[2] + dy[k];
            if (N >= 3) {
              if (!move(tx[2], ty[2], 2) || (crash(tx, ty, g.x, g.y, 3))) {
                tx[2] = g.x[2];
                ty[2] = g.y[2];
                continue;
              }
            }
            for (int l = 0; l < 3; l++) {
              th[l] = (tx[l] << 4) + ty[l];
            }

            if (h[th[0]][th[1]][th[2]][g.r]) {
              tx[2] = g.x[2];
              ty[2] = g.y[2];
              continue;
            }
            h[th[0]][th[1]][th[2]][g.r] = g.c;

            q.push(Ghost(tx, ty, g.c + 1, g.r));
          }
        }
      }
    }
  }
}

Fixed submission:
#include <cctype>
#include <cstdio>
#include <cstring>
#include <iostream>
#include <queue>
#include <string>
using namespace std;

char f[16][16];
int fx, fy, N;
int dx[] = {0, 0, -1, 1, 0};
int dy[] = {0, -1, 0, 0, 1};

class Ghost {
public:
  int x[3], y[3], c;
  bool r;

  Ghost(int *i, int *j, int c, bool r) : r(r), c(c) {
    for (int k = 0; k < 3; k++) {
      x[k] = i[k];
      y[k] = j[k];
    }
  }
};

bool move(int x, int y, int p) {
  if (p >= N)
    return true;
  if (x < 0 || y < 0 || x >= fx || y >= fy)
    return false;
  if (f[x][y] == '#')
    return false;

  return true;
}

bool crash(int *x, int *y, int *gx, int *gy, int p) {
  if (p < N)
    return false;
  for (int i = 0; i < p; i++)
    for (int j = i + 1; j < p; j++) {
      if (x[i] == x[j] && y[i] == y[j])
        return true;
      if (x[i] == gx[j] && y[i] == gy[j] && gx[i] == x[j] && gy[i] == y[j])
        return true;
    }
  return false;
}

unsigned char h[256][256][256][2];

int main() {
  while (scanf("%d%d%d", &fx, &fy, &N), (fx || fy || N)) {
    int sx[3] = {0}, sy[3] = {0}, gx[3] = {0}, gy[3] = {0};
    memset(h, 0, sizeof(h));

    string s;

    getchar();
    for (int i = 0; i < fy; i++) {
      getline(cin, s);
      for (int j = 0; j < fx; j++) {
        if (islower(s[j])) {
          sx[s[j] - 'a'] = j;
          sy[s[j] - 'a'] = i;
        }
        if (isupper(s[j])) {
          gx[s[j] - 'A'] = j;
          gy[s[j] - 'A'] = i;
        }

        f[j][i] = s[j];
      }
    }

    queue<Ghost> q;
    q.push(Ghost(sx, sy, 1, 0));
    q.push(Ghost(gx, gy, 1, 1));

    int th[3];
    for (int l = 0; l < 3; l++) {
      th[l] = (sx[l] << 4) + sy[l];
    }
    h[th[0]][th[1]][th[2]][0] = 1;
    for (int l = 0; l < 3; l++) {
      th[l] = (gx[l] << 4) + gy[l];
    }
    h[th[0]][th[1]][th[2]][1] = 1;

    while (!q.empty()) {
      Ghost g = q.front();
      q.pop();

      int th[3];

      for (int l = 0; l < 3; l++) {
        th[l] = (g.x[l] << 4) + g.y[l];
      }

      if (h[th[0]][th[1]][th[2]][!g.r]) {
        printf("%d\n", g.c + h[th[0]][th[1]][th[2]][!g.r] - 1);
        break;
      }

      int tx[3], ty[3];
      for (int i = 0; i < 3; i++) {
        tx[i] = g.x[i];
        ty[i] = g.y[i];
      }

      for (int i = 0; i < 5; i++) {
        tx[0] = g.x[0] + dx[i], ty[0] = g.y[0] + dy[i];
        if (!move(tx[0], ty[0], 0)) {
          tx[0] = g.x[0];
          ty[0] = g.y[0];
          continue;
        }

        for (int j = 0; j < (N > 1 ? 5 : 1); j++) {
          tx[1] = g.x[1] + dx[j], ty[1] = g.y[1] + dy[j];
          if (N >= 2) {
            if (!move(tx[1], ty[1], 1) || (crash(tx, ty, g.x, g.y, 2))) {
              tx[1] = g.x[1];
              ty[1] = g.y[1];
              continue;
            }
          }

          for (int k = 0; k < (N > 2 ? 5 : 1); k++) {
            tx[2] = g.x[2] + dx[k], ty[2] = g.y[2] + dy[k];
            if (N >= 3) {
              if (!move(tx[2], ty[2], 2) || (crash(tx, ty, g.x, g.y, 3))) {
                tx[2] = g.x[2];
                ty[2] = g.y[2];
                continue;
              }
            }
            for (int l = 0; l < 3; l++) {
              th[l] = (tx[l] << 4) + ty[l];
            }

            if (h[th[0]][th[1]][th[2]][g.r]) {
              tx[2] = g.x[2];
              ty[2] = g.y[2];
              continue;
            }
            h[th[0]][th[1]][th[2]][g.r] = g.c;

            q.push(Ghost(tx, ty, g.c + 1, g.r));
          }
        }
      }
    }
  }
}