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

#include <bits/stdc++.h>
#define INF (1e9)
#define N 14
#define rep(i, n) for (int i = 0; i < n; i++)
using namespace std;

struct dat {
  int cost, ay, ax, by, bx, cy, cx;
};

int w, h, n;
int d[N][N][N][N][N][N];
string s[16];
int ay, ax, by, bx, cy, cx;
int dy[5] = {-1, 0, 1, 0, 0};
int dx[5] = {0, 1, 0, -1, 0};

queue<dat> q;

bool check(int nay, int nax) {
  if (nay < 0 || nax < 0 || h <= nay || w <= nax)
    return false;
  if (s[nay][nax] == '#')
    return false;
  return true;
}

bool check2(int Ay, int Ax, int By, int Bx, int ai, int bi) {

  if (Ay == By) {
    if (Ax + 1 == Bx && ai == 1 && bi == 3)
      return false;
    if (Bx + 1 == Ax && bi == 1 && ai == 3)
      return false;
  }

  if (Ax == Bx) {
    if (Ay + 1 == By && ai == 2 && bi == 0)
      return false;
    if (By + 1 == Ay && bi == 2 && ai == 0)
      return false;
  }

  return true;
}

int bnf() {

  rep(i, N) rep(j, N) rep(k, N) rep(l, N) rep(m, N) rep(o, N)
      d[i][j][k][l][m][o] = INF;

  d[ay][ax][by][bx][cy][cx] = 0;
  q.push(dat{0, ay, ax, by, bx, cy, cx});

  int res;

  while (!q.empty()) {

    dat t = q.front();
    q.pop();

    if (n == 1 && s[t.ay][t.ax] == 'A' + s[ay][ax] - 'a') {
      res = t.cost;
      break;
    }

    if (n == 2 && s[t.ay][t.ax] == 'A' + s[ay][ax] - 'a' &&
        s[t.by][t.bx] == 'A' + s[by][bx] - 'a') {
      res = t.cost;
      break;
    }

    if (n == 3 && s[t.ay][t.ax] == 'A' + s[ay][ax] - 'a' &&
        s[t.by][t.bx] == 'A' + s[by][bx] - 'a' &&
        s[t.cy][t.cx] == 'A' + s[cy][cx] - 'a') {
      res = t.cost;
      break;
    }

    rep(i, 5) {
      int nay = dy[i] + t.ay, nax = dx[i] + t.ax;
      if (!check(nay, nax))
        continue;

      rep(j, 5) {
        int nby = dy[j] + t.by, nbx = dx[j] + t.bx;
        if (n == 1)
          nby = 0, nbx = 0;
        if (n >= 2 && !check(nby, nbx))
          continue;

        rep(k, 5) {

          int ncy = dy[k] + t.cy, ncx = dx[k] + t.cx;
          if (n <= 2)
            ncy = 0, ncx = 0;
          if (n == 3 && !check(ncy, ncx))
            continue;

          if (n >= 2 && !check2(t.ay, t.ax, t.by, t.bx, i, j))
            continue;
          if (n == 3 && !check2(t.ay, t.ax, t.cy, t.cx, i, k))
            continue;
          if (n == 3 && !check2(t.by, t.bx, t.cy, t.cx, j, k))
            continue;

          if (n >= 2 && nay == nby && nax == nbx)
            continue;
          if (n == 3 && nay == ncy && nax == ncx)
            continue;
          if (n == 3 && nby == ncy && nbx == ncx)
            continue;

          if (d[nay][nax][nby][nbx][ncy][ncx] >
              d[t.ay][t.ax][t.by][t.bx][t.cy][t.cx] + 1) {
            d[nay][nax][nby][nbx][ncy][ncx] =
                d[t.ay][t.ax][t.by][t.bx][t.cy][t.cx] + 1;
            q.push(dat{d[nay][nax][nby][nbx][ncy][ncx], nay, nax, nby, nbx, ncy,
                       ncx});
          }
        }
      }
    }
  }

  return res;
}

int main() {

  while (1) {

    cin >> w >> h >> n;
    if (!w && !h && !n)
      break;

    unordered_set<char> memo;

    ay = ax = by = bx = cy = cx = 0;

    getline(cin, s[0]);
    rep(i, h) getline(cin, s[i]);

    for (int i = 0; i < h - 2; i++) {
      s[i] = s[i + 1];
      s[i] = s[i].substr(1, w - 2);
      rep(j, w - 2) {
        char c = s[i][j];
        if ('a' <= c && c <= 'z' && !memo.count(c)) {
          if (memo.size() == 0)
            ay = i, ax = j;
          if (memo.size() == 1)
            by = i, bx = j;
          if (memo.size() == 2)
            cy = i, cx = j;
          memo.insert(c);
        }
      }
    }

    h -= 2;
    w -= 2;

    cout << bnf() << endl;
  }

  return 0;
}

Error: MLE

Fixed submission:

#include <bits/stdc++.h>
#define INF (1e9)
#define N 16
#define rep(i, n) for (int i = 0; i < n; i++)
using namespace std;

struct dat {
  int cost, ay, ax, by, bx, cy, cx;
};

int w, h, n;
int d[N][N][N][N][N][N];
string s[16];
int ay, ax, by, bx, cy, cx;
int dy[5] = {-1, 0, 1, 0, 0};
int dx[5] = {0, 1, 0, -1, 0};

queue<dat> q;

bool check(int nay, int nax) {
  if (nay < 0 || nax < 0 || h <= nay || w <= nax)
    return false;
  if (s[nay][nax] == '#')
    return false;
  return true;
}

bool check2(int Ay, int Ax, int By, int Bx, int ai, int bi) {

  if (Ay == By) {
    if (Ax + 1 == Bx && ai == 1 && bi == 3)
      return false;
    if (Bx + 1 == Ax && bi == 1 && ai == 3)
      return false;
  }

  if (Ax == Bx) {
    if (Ay + 1 == By && ai == 2 && bi == 0)
      return false;
    if (By + 1 == Ay && bi == 2 && ai == 0)
      return false;
  }

  return true;
}

int bnf() {

  rep(i, N) rep(j, N) rep(k, N) rep(l, N) rep(m, N) rep(o, N)
      d[i][j][k][l][m][o] = (1e4);

  d[ay][ax][by][bx][cy][cx] = 0;
  q.push(dat{0, ay, ax, by, bx, cy, cx});

  int res;

  while (!q.empty()) {

    dat t = q.front();
    q.pop();

    if (s[t.ay][t.ax] == 'A' + s[ay][ax] - 'a' &&
        s[t.by][t.bx] == 'A' + s[by][bx] - 'a' &&
        s[t.cy][t.cx] == 'A' + s[cy][cx] - 'a') {
      res = t.cost;
      break;
    }

    rep(i, 5) {
      int nay = dy[i] + t.ay, nax = dx[i] + t.ax;
      if (!check(nay, nax))
        continue;

      rep(j, 5) {
        int nby = dy[j] + t.by, nbx = dx[j] + t.bx;
        if (!check(nby, nbx))
          continue;

        rep(k, 5) {

          int ncy = dy[k] + t.cy, ncx = dx[k] + t.cx;
          if (!check(ncy, ncx))
            continue;

          if (!check2(t.ay, t.ax, t.by, t.bx, i, j))
            continue;
          if (!check2(t.ay, t.ax, t.cy, t.cx, i, k))
            continue;
          if (!check2(t.by, t.bx, t.cy, t.cx, j, k))
            continue;

          if (nay == nby && nax == nbx)
            continue;
          if (nay == ncy && nax == ncx)
            continue;
          if (nby == ncy && nbx == ncx)
            continue;

          if (d[nay][nax][nby][nbx][ncy][ncx] >
              d[t.ay][t.ax][t.by][t.bx][t.cy][t.cx] + 1) {
            d[nay][nax][nby][nbx][ncy][ncx] =
                d[t.ay][t.ax][t.by][t.bx][t.cy][t.cx] + 1;
            q.push(dat{d[nay][nax][nby][nbx][ncy][ncx], nay, nax, nby, nbx, ncy,
                       ncx});
          }
        }
      }
    }
  }

  return res;
}

int main() {

  while (1) {

    cin >> w >> h >> n;
    if (!w && !h && !n)
      break;

    unordered_set<char> memo;

    getline(cin, s[0]);
    rep(i, h) {
      getline(cin, s[i]);
      rep(j, w) {
        char c = s[i][j];
        if ('a' <= c && c <= 'z' && !memo.count(c)) {
          if (memo.size() == 0)
            ay = i, ax = j;
          if (memo.size() == 1)
            by = i, bx = j;
          if (memo.size() == 2)
            cy = i, cx = j;
          memo.insert(c);
        }
      }
    }

    if (n <= 1) {
      for (int i = 'a'; i <= 'z'; i++)
        if (!memo.count((char)i)) {
          memo.insert((char)i);
          s[0][0] = (char)i;
          s[0][1] = char('A' + i - 'a');
          by = 0, bx = 0;
        }
    }

    if (n <= 2) {
      for (int i = 'a'; i <= 'z'; i++)
        if (!memo.count((char)i)) {
          memo.insert((char)i);
          s[0][2] = (char)i;
          s[0][3] = char('A' + i - 'a');
          cy = 0, cx = 2;
        }
    }

    memo.clear();

    cout << bnf() << endl;
  }

  return 0;
}