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

#include <algorithm>
#include <climits>
#include <cmath>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <functional>
#include <iostream>
#include <map>
#include <numeric>
#include <queue>
#include <set>
#include <sstream>
#include <stack>
#include <string>
#include <vector>
using namespace std;

typedef istringstream ISS;
typedef ostringstream OSS;
typedef vector<string> VS;
typedef char INT;
typedef vector<INT> VI;
typedef vector<VI> VVI;
typedef pair<INT, INT> II;
typedef vector<II> VII;

template <class T> ostream &operator<<(ostream &os, vector<T> v) {
  for (typename vector<T>::iterator it_i = v.begin(); it_i != v.end(); ++it_i) {
    os << *it_i << ", ";
  }
  return os;
}

int W, H;
VS M;
map<II, int> ID;
int CID;

void setCellID(int r, int c) {
  if (ID.count(II(r, c)))
    return;
  ID[II(r, c)] = CID++;
}

int getCellID(int r, int c) { return ID[II(r, c)]; }

void init() {
  ID.clear();
  CID = 0;

  for (int i = 0; i < H; ++i) {
    for (int j = 0; j < W; ++j) {
      if (M[i][j] == '#')
        continue;
      setCellID(i, j);
    }
  }
}

bool input() {
  if (!(cin >> W >> H && W))
    return false;
  M = VS(H);
  for (int i = 0; i < H; ++i) {
    cin >> M[i];
  }
  return true;
}

typedef pair<II, int> STATE;
typedef pair<int, STATE> NODE;
typedef queue<NODE> QUEUE;
typedef set<STATE> VISITED;
const int dr[4] = {0, 0, 1, -1};
const int dc[4] = {1, -1, 0, 0};
char rr[3];
char rc[3];
QUEUE Q;
bool V[51][51][51][51];

STATE getState(int r, int c) {
  int bitState = 0;
  for (int i = 0; i < 3; ++i) {
    bitState <<= 8;
    bitState |= ((rr[i] - 1) << 4) | (rc[i] - 1);
  }
  return STATE(II(r, c), bitState);
}

II deployState(STATE state) {
  for (int i = 2; i >= 0; --i) {
    rr[i] = ((state.second & 0xF0) >> 4) + 1;
    rc[i] = (state.second & 0x0F) + 1;
    state.second >>= 8;
  }
  return state.first;
}

int solve() {
  Q = QUEUE();
  fill((bool *)V, (bool *)V + 51 * 51 * 51 * 51, false);
  char sr, sc;
  int rocks = 0, marks = 0;
  char rr_[3], rc_[3];
  char mr[3], mc[3];

  for (int i = 0; i < H; ++i) {
    for (int j = 0; j < W; ++j) {
      if (M[i][j] == '@') {
        sr = i;
        sc = j;
        M[i][j] = '.';
      } else if (M[i][j] == '*') {
        rr_[rocks] = i;
        rc_[rocks] = j;
        rocks++;
        M[i][j] = '.';
      } else if (M[i][j] == '_') {
        mr[marks] = i;
        mc[marks] = j;
        marks++;
        M[i][j] = '.';
      }
    }
  }

  for (int i = 0; i < 3; ++i) {
    rr[i] = rr_[i];
    rc[i] = rc_[i];
  }

  Q.push(NODE(0, getState(sr, sc)));
  V[getCellID(sr, sc)][getCellID(rr[0], rc[0])][getCellID(rr[1], rc[1])]
   [getCellID(rr[2], rc[2])] = true;

  cin.ignore();
  cin.clear();

  while (!Q.empty()) {
    NODE node = Q.front();
    Q.pop();

    int steps = node.first;
    STATE state = node.second;
    II ret = deployState(state);
    char r = ret.first;
    char c = ret.second;

    bool checked[3];
    fill(checked, checked + 3, false);
    for (int i = 0; i < 3; ++i) {
      for (int j = 0; j < 3; ++j) {
        if (rr[i] == mr[j] && rc[i] == mc[j]) {
          checked[j] = true;
        }
      }
    }
    if (count(checked, checked + 3, true) == 3) {
      return steps;
    }

    for (int i = 0; i < 4; ++i) {
      deployState(state);
      int nr = r + dr[i];
      int nc = c + dc[i];
      if (nr < 0 || nr >= H || nc < 0 || nc >= W)
        continue;
      bool flag = false;
      for (int j = 0; j < 3; ++j) {
        if (nr == rr[j] && nc == rc[j]) {
          int nnr = nr + dr[i];
          int nnc = nc + dc[i];
          if (nnr < 0 || nnr >= H || nnc < 0 || nnc >= W) {
            flag = true;
            break;
          }
          if (M[nnr][nnc] == '#') {
            flag = true;
            break;
          }
          for (int k = 0; k < 3; ++k) {
            if (nnr == rr[k] && nnc == rc[k]) {
              flag = true;
              break;
            }
          }
          if (flag)
            break;
          rr[j] = nnr;
          rc[j] = nnc;
          break;
        }
      }
      if (flag)
        continue;
      if (M[nr][nc] == '#')
        continue;
      int nsteps = steps + 1;
      STATE state = getState(nr, nc);
      int a = getCellID(nr, nc);
      int b = getCellID(rr[0], rc[0]);
      int c = getCellID(rr[1], rc[1]);
      int d = getCellID(rr[2], rc[2]);
      if (V[a][b][c][d])
        continue;
      V[a][b][c][d] = true;
      NODE next(nsteps, state);
      Q.push(next);
    }
  }

  return -1;
}

int main() {
  while (input()) {
    init();
    cout << solve() << endl;
  }
  return 0;
}

Error: MLE

Fixed submission:

#include <algorithm>
#include <climits>
#include <cmath>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <functional>
#include <iostream>
#include <map>
#include <numeric>
#include <queue>
#include <set>
#include <sstream>
#include <stack>
#include <string>
#include <vector>
using namespace std;

typedef istringstream ISS;
typedef ostringstream OSS;
typedef vector<string> VS;
typedef char INT;
typedef vector<INT> VI;
typedef vector<VI> VVI;
typedef pair<INT, INT> II;
typedef vector<II> VII;

template <class T> ostream &operator<<(ostream &os, vector<T> v) {
  for (typename vector<T>::iterator it_i = v.begin(); it_i != v.end(); ++it_i) {
    os << *it_i << ", ";
  }
  return os;
}

int W, H;
VS M;

bool input() {
  if (!(cin >> W >> H && W))
    return false;
  M = VS(H);
  for (int i = 0; i < H; ++i) {
    cin >> M[i];
  }
  return true;
}

typedef pair<II, int> STATE;
typedef pair<int, STATE> NODE;
typedef queue<NODE> QUEUE;
typedef set<STATE> VISITED;
const int dr[4] = {0, 0, 1, -1};
const int dc[4] = {1, -1, 0, 0};
char rr[3];
char rc[3];
QUEUE Q;
VISITED V;

STATE getState(int r, int c) {
  int bitState = 0;
  for (int i = 0; i < 3; ++i) {
    bitState <<= 8;
    bitState |= (rr[i] << 4) | rc[i];
  }
  return STATE(II(r, c), bitState);
}

II deployState(STATE state) {
  for (int i = 2; i >= 0; --i) {
    rr[i] = (state.second & 0xF0) >> 4;
    rc[i] = state.second & 0x0F;
    state.second >>= 8;
  }
  return state.first;
}

int solve() {
  Q = QUEUE();
  V.clear();
  char sr, sc;
  int rocks = 0, marks = 0;
  char rr_[3], rc_[3];
  char mr[3], mc[3];

  for (int i = 0; i < H; ++i) {
    for (int j = 0; j < W; ++j) {
      if (M[i][j] == '@') {
        sr = i;
        sc = j;
        M[i][j] = '.';
      } else if (M[i][j] == '*') {
        rr_[rocks] = i;
        rc_[rocks] = j;
        rocks++;
        M[i][j] = '.';
      } else if (M[i][j] == '_') {
        mr[marks] = i;
        mc[marks] = j;
        marks++;
        M[i][j] = '.';
      }
    }
  }

  for (int i = 0; i < 3; ++i) {
    rr[i] = rr_[i];
    rc[i] = rc_[i];
  }

  Q.push(NODE(0, getState(sr, sc)));
  V.insert(getState(sr, sc));

  cin.ignore();
  cin.clear();

  while (!Q.empty()) {
    NODE node = Q.front();
    Q.pop();

    int steps = node.first;
    STATE state = node.second;
    II ret = deployState(state);
    char r = ret.first;
    char c = ret.second;

    bool checked[3];
    fill(checked, checked + 3, false);
    for (int i = 0; i < 3; ++i) {
      for (int j = 0; j < 3; ++j) {
        if (rr[i] == mr[j] && rc[i] == mc[j]) {
          checked[j] = true;
        }
      }
    }
    if (count(checked, checked + 3, true) == 3) {
      return steps;
    }

    for (int i = 0; i < 4; ++i) {
      deployState(state);
      int nr = r + dr[i];
      int nc = c + dc[i];
      if (nr < 0 || nr >= H || nc < 0 || nc >= W)
        continue;
      bool flag = false;
      for (int j = 0; j < 3; ++j) {
        if (nr == rr[j] && nc == rc[j]) {
          int nnr = nr + dr[i];
          int nnc = nc + dc[i];
          if (nnr < 0 || nnr >= H || nnc < 0 || nnc >= W) {
            flag = true;
            break;
          }
          if (M[nnr][nnc] == '#') {
            flag = true;
            break;
          }
          for (int k = 0; k < 3; ++k) {
            if (nnr == rr[k] && nnc == rc[k]) {
              flag = true;
              break;
            }
          }
          if (flag)
            break;
          rr[j] = nnr;
          rc[j] = nnc;
          break;
        }
      }
      if (flag)
        continue;
      if (M[nr][nc] == '#')
        continue;
      int nsteps = steps + 1;
      STATE state = getState(nr, nc);
      if (V.count(state))
        continue;
      V.insert(state);
      NODE next(nsteps, state);
      Q.push(next);
    }
  }

  return -1;
}

int main() {
  while (input()) {
    cout << solve() << endl;
  }
  return 0;
}