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

#include <bits/stdc++.h>
using namespace std;

const int H = 19;
const int W = 15;

struct State {
  int xstate;
  unsigned char h, w;

  bool operator<(const State &r) const {
    int xl = xstate * H * W + h * W + w;
    int xr = r.xstate * H * W + r.h * W + r.w;
    return xl < xr;
  }
};

vector<string> board(H);
vector<int> xhs, xws;
map<State, int> d;

bool infield(int h, int w) {
  if (h == H)
    return true;
  else
    return 0 <= w && w < W;
}

int bfs(int sh, int sw) {
  int xn = xhs.size();
  map<pair<int, int>, int> ipoint;
  for (int i = 0; i < xn; i++)
    ipoint[{xhs[i], xws[i]}] = i;

  queue<State> que;
  State s;
  s.xstate = (1 << xn) - 1;
  s.h = sh;
  s.w = sw;
  que.push(s);

  d[s] = 0;

  int maxq = 0;

  while (!que.empty()) {
    maxq = max(maxq, (int)que.size());
    auto s = que.front();
    que.pop();
    // cout << que.size() << endl;

    for (int dh = -1; dh <= 1; dh++) {
      for (int dw = -1; dw <= 1; dw++)
        if (dh != 0 || dw != 0) {
          State ns;
          ns.xstate = s.xstate;
          ns.h = s.h + dh;
          ns.w = s.w + dw;

          if (ipoint.find({ns.h, ns.w}) == ipoint.end() ||
              ((ns.xstate >> ipoint[{ns.h, ns.w}]) & 1) == 0)
            continue;

          int count = 0;
          while (infield(ns.h, ns.w) &&
                 ipoint.find({ns.h, ns.w}) != ipoint.end() &&
                 (ns.xstate >> ipoint[{ns.h, ns.w}]) & 1) {
            ns.h += dh;
            ns.w += dw;
            count++;
          }
          if (!infield(ns.h, ns.w))
            continue;

          ns.h = s.h + dh;
          ns.w = s.w + dw;
          for (int i = 0; i < count; i++) {
            ns.xstate -= 1 << ipoint[{ns.h, ns.w}];
            ns.h += dh;
            ns.w += dw;
          }

          if (d.find(ns) != d.end())
            continue;

          que.push(ns);
          d[ns] = d[s] + 1;

          if (H - 1 <= ns.h) {
            return d[ns];
          }
        }
    }
  }
  // cout << maxq << endl;
  return -1;
}

int main() {
  for (auto &s : board)
    cin >> s;

  int sh, sw;
  for (int h = 0; h < H; h++) {
    for (int w = 0; w < W; w++) {
      if (board[h][w] == 'O')
        sh = h, sw = w;
      if (board[h][w] == 'X')
        xhs.push_back(h), xws.push_back(w);
    }
  }
  cout << bfs(sh, sw) << endl;

  return 0;
}

Error: MLE

Fixed submission:

#include <bits/stdc++.h>
using namespace std;

const int H = 19;
const int W = 15;
vector<string> board(H);
vector<int> xhs, xws;
int d[1 << 20][H][W];

struct State {
  int xstate;
  unsigned char h, w;

  //    bool operator < (const State &r) const{
  //        int xl = xstate * H * W + h * W + w;
  //        int xr = r.xstate * H * W + r.h * W + r.w;
  //        return xl < xr;
  //    }
};

inline bool infield(int h, int w) {
  if (h == H)
    return true;
  else
    return 0 <= w && w < W;
}

int bfs(int sh, int sw) {
  int xn = xhs.size();
  map<pair<int, int>, int> ipoint;
  for (int i = 0; i < xn; i++)
    ipoint[{xhs[i], xws[i]}] = i;

  queue<State> que;
  State s;
  s.xstate = (1 << xn) - 1;
  s.h = sh;
  s.w = sw;
  que.push(s);

  memset(d, -1, sizeof(d));
  d[s.xstate][s.h][s.w] = 0;

  while (!que.empty()) {
    auto s = que.front();
    que.pop();

    for (int dh = -1; dh <= 1; dh++) {
      for (int dw = -1; dw <= 1; dw++)
        if (dh != 0 || dw != 0) {
          State ns;
          ns.xstate = s.xstate;
          ns.h = s.h + dh;
          ns.w = s.w + dw;

          if (ipoint.find({ns.h, ns.w}) == ipoint.end() ||
              ((ns.xstate >> ipoint[{ns.h, ns.w}]) & 1) == 0)
            continue;

          int count = 0;
          while (infield(ns.h, ns.w) &&
                 ipoint.find({ns.h, ns.w}) != ipoint.end() &&
                 (ns.xstate >> ipoint[{ns.h, ns.w}]) & 1) {
            ns.h += dh;
            ns.w += dw;
            count++;
          }
          if (!infield(ns.h, ns.w))
            continue;

          ns.h = s.h + dh;
          ns.w = s.w + dw;
          for (int i = 0; i < count; i++) {
            ns.xstate -= 1 << ipoint[{ns.h, ns.w}];
            ns.h += dh;
            ns.w += dw;
          }

          if (d[ns.xstate][ns.h][ns.w] >= 0)
            continue;

          que.push(ns);
          d[ns.xstate][ns.h][ns.w] = d[s.xstate][s.h][s.w] + 1;

          if (H - 1 <= ns.h) {
            return d[ns.xstate][ns.h][ns.w];
          }
        }
    }
  }
  return -1;
}

int main() {
  for (auto &s : board)
    cin >> s;

  int sh, sw;
  for (int h = 0; h < H; h++) {
    for (int w = 0; w < W; w++) {
      if (board[h][w] == 'O')
        sh = h, sw = w;
      if (board[h][w] == 'X')
        xhs.push_back(h), xws.push_back(w);
    }
  }
  cout << bfs(sh, sw) << endl;

  return 0;
}