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

/*
 * D.cpp
 *
 *  Created on: Oct 11, 2013
 *      Author: Hesham
 */
#include <algorithm>
#include <bitset>
#include <cassert>
#include <cmath>
#include <cstring>
#include <ctime>
#include <ctype.h>
#include <fstream>
#include <iomanip>
#include <iostream>
#include <map>
#include <queue>
#include <set>
#include <sstream>
#include <stack>
#include <stdio.h>
#include <string>
#include <vector>
using namespace std;
int dx[] = {0, 0, 1, -1, 0};
int dy[] = {0, 1, 0, 0, -1};
int w, h, n;
string house[16];
struct State {
  vector<int> y, x;
  State() {
    x.resize(3, 0);
    y.resize(3, 0);
  }
  State(vector<int> &yy, vector<int> &xx) : x(xx), y(yy) {}
  bool operator==(const State &other) const {
    return x == other.x && y == other.y;
  }
};
bool vis1[16][16][16][16][16][16];
bool vis2[16][16][16][16][16][16];
// short dist[16][16][16][16][16][16];

bool isVis(State &s, bool vis[16][16][16][16][16][16]) {
  return vis[s.x[0]][s.x[1]][s.x[2]][s.y[0]][s.y[1]][s.y[2]];
}
void setVis(State &s, bool vis[16][16][16][16][16][16]) {
  vis[s.x[0]][s.x[1]][s.x[2]][s.y[0]][s.y[1]][s.y[2]] = true;
}
/*int getDist(State& s) {
        return dist[s.x[0]][s.x[1]][s.x[2]][s.y[0]][s.y[1]][s.y[2]];
}*/
/*void setDist(State& s, int v) {
        dist[s.x[0]][s.x[1]][s.x[2]][s.y[0]][s.y[1]][s.y[2]] = v;
}*/

bool ok(int y, int x) {
  if (y < 0 || y == h || x < 0 || x == w)
    return false;
  if (house[y][x] == '#')
    return false;
  return true;
}
int d1, d2;
int c11, c12, c21, c22;
int pushAdjs(int i, State &adj, State &curr, queue<State> &q,
             bool visA[16][16][16][16][16][16],
             bool visB[16][16][16][16][16][16], int da, int db, int &c) {
  if (i == n) {
    if (isVis(adj, visA))
      return -1;
    if (isVis(adj, visB))
      return da + 1 + db;
    setVis(adj, visA);
    q.push(adj);
    ++c;
    return -1;
  }
  for (int d = 0; d < 5; ++d) {
    adj.y[i] = dy[d] + curr.y[i];
    adj.x[i] = dx[d] + curr.x[i];
    if (!ok(adj.y[i], adj.x[i]))
      continue;
    bool okk = true;
    for (int j = 0; j < i; ++j) {
      if (adj.y[i] == curr.y[j] && adj.x[i] == curr.x[j] &&
          adj.y[j] == curr.y[i] && adj.x[j] == curr.x[i]) {
        okk = false;
        break;
      }
      if (adj.y[i] == adj.y[j] && adj.x[i] == adj.x[j]) {
        okk = false;
        break;
      }
    }
    if (!okk)
      continue;
    int cost = pushAdjs(i + 1, adj, curr, q, visA, visB, da, db, c);
    if (cost != -1)
      return cost;
  }
  return -1;
}
int meetMiddle(vector<int> &sy, vector<int> &sx, vector<int> &ty,
               vector<int> &tx) {
  memset(vis1, false, sizeof vis1);
  memset(vis2, false, sizeof vis2);
  State s(sy, sx);
  State t(ty, tx);
  // setDist(s, 0);
  // setDist(t, 0);
  d1 = 0;
  d2 = 0;
  c11 = 1, c12 = 0, c21 = 1, c22 = 0;
  setVis(s, vis1);
  setVis(t, vis2);
  queue<State> q1;
  queue<State> q2;
  q1.push(s);
  q2.push(t);
  while (true) {
    if (d1 <= d2) {
      State curr1 = q1.front();
      q1.pop();
      --c11;
      State adj;
      int cost = pushAdjs(0, adj, curr1, q1, vis1, vis2, d1, d2, c12);
      if (cost != -1)
        return cost;
      if (!c11) {
        swap(c11, c12);
        d1++;
      }
    }
    if (d2 < d1) {
      State curr2 = q2.front();
      q2.pop();
      --c21;
      State adj;
      int cost = pushAdjs(0, adj, curr2, q2, vis2, vis1, d2, d1, c22);
      if (cost != -1)
        return cost;
      if (!c21) {
        swap(c21, c22);
        d2++;
      }
    }
  }
  return -1;
}

int main() {

  // freopen("in.txt", "r", stdin);
  // clock_t begin = clock();
  string line;
  while (cin >> w >> h >> n) {
    if (!w && !h && !n)
      break;
    cin.ignore();
    cin.ignore();
    for (int i = 0; i < h; ++i)
      getline(cin, house[i]);

    vector<int> sx(3, 0);
    vector<int> sy(3, 0);

    vector<int> tx(3, 0);
    vector<int> ty(3, 0);
    for (int i = 0; i < h; ++i) {
      for (int j = 0; j < w; ++j) {
        if (house[i][j] >= 'A' && house[i][j] <= 'C') {
          tx[(house[i][j] - 'A')] = j;
          ty[(house[i][j] - 'A')] = i;
        }
        if (house[i][j] >= 'a' && house[i][j] <= 'c') {
          sx[(house[i][j] - 'a')] = j;
          sy[(house[i][j] - 'a')] = i;
        }
      }
    }

    cout << meetMiddle(sy, sx, ty, tx) << endl;
  }
}

Error: MLE

Fixed submission:

/*
 * D.cpp
 *
 *  Created on: Oct 11, 2013
 *      Author: Hesham
 */
#include <algorithm>
#include <bitset>
#include <cassert>
#include <cmath>
#include <cstring>
#include <ctime>
#include <ctype.h>
#include <fstream>
#include <iomanip>
#include <iostream>
#include <map>
#include <queue>
#include <set>
#include <sstream>
#include <stack>
#include <stdio.h>
#include <string>
#include <vector>
using namespace std;
int dx[] = {0, 0, 1, -1, 0};
int dy[] = {0, 1, 0, 0, -1};
int w, h, n;
string house[16];
struct State {
  vector<int> y, x;
  State() {
    x.resize(3, 0);
    y.resize(3, 0);
  }
  State(vector<int> &yy, vector<int> &xx) : x(xx), y(yy) {}
  bool operator==(const State &other) const {
    return x == other.x && y == other.y;
  }
};
bool vis1[16][16][16][16][16][16];
bool vis2[16][16][16][16][16][16];
short dist[16][16][16][16][16][16];

bool isVis(State &s, bool vis[16][16][16][16][16][16]) {
  return vis[s.x[0]][s.x[1]][s.x[2]][s.y[0]][s.y[1]][s.y[2]];
}
void setVis(State &s, bool vis[16][16][16][16][16][16]) {
  vis[s.x[0]][s.x[1]][s.x[2]][s.y[0]][s.y[1]][s.y[2]] = true;
}
int getDist(State &s) {
  return dist[s.x[0]][s.x[1]][s.x[2]][s.y[0]][s.y[1]][s.y[2]];
}
void setDist(State &s, int v) {
  dist[s.x[0]][s.x[1]][s.x[2]][s.y[0]][s.y[1]][s.y[2]] = v;
}

bool ok(int y, int x) {
  if (y < 0 || y == h || x < 0 || x == w)
    return false;
  if (house[y][x] == '#')
    return false;
  return true;
}
int pushAdjs(int i, State &adj, State &curr, queue<State> &q,
             bool visA[16][16][16][16][16][16],
             bool visB[16][16][16][16][16][16]) {
  if (i == n) {
    if (isVis(adj, visA))
      return -1;
    if (isVis(adj, visB))
      return getDist(curr) + 1 + getDist(adj);
    setDist(adj, getDist(curr) + 1);
    setVis(adj, visA);
    q.push(adj);
    return -1;
  }
  for (int d = 0; d < 5; ++d) {
    adj.y[i] = dy[d] + curr.y[i];
    adj.x[i] = dx[d] + curr.x[i];
    if (!ok(adj.y[i], adj.x[i]))
      continue;
    bool okk = true;
    for (int j = 0; j < i; ++j) {
      if (adj.y[i] == curr.y[j] && adj.x[i] == curr.x[j] &&
          adj.y[j] == curr.y[i] && adj.x[j] == curr.x[i]) {
        okk = false;
        break;
      }
      if (adj.y[i] == adj.y[j] && adj.x[i] == adj.x[j]) {
        okk = false;
        break;
      }
    }
    if (!okk)
      continue;
    int cost = pushAdjs(i + 1, adj, curr, q, visA, visB);
    if (cost != -1)
      return cost;
  }
  return -1;
}
int meetMiddle(vector<int> &sy, vector<int> &sx, vector<int> &ty,
               vector<int> &tx) {
  memset(vis1, false, sizeof vis1);
  memset(vis2, false, sizeof vis2);
  State s(sy, sx);
  State t(ty, tx);
  setDist(s, 0);
  setDist(t, 0);
  setVis(s, vis1);
  setVis(t, vis2);
  queue<State> q1;
  queue<State> q2;
  q1.push(s);
  q2.push(t);
  while (true) {
    {
      State curr1 = q1.front();
      q1.pop();
      State adj;
      int cost = pushAdjs(0, adj, curr1, q1, vis1, vis2);
      if (cost != -1)
        return cost;
    }
    {
      State curr2 = q2.front();
      q2.pop();
      State adj;
      int cost = pushAdjs(0, adj, curr2, q2, vis2, vis1);
      if (cost != -1)
        return cost;
    }
  }
  return -1;
}

int main() {

  // freopen("in.txt", "r", stdin);
  // clock_t begin = clock();
  string line;
  while (cin >> w >> h >> n) {
    if (!w && !h && !n)
      break;
    cin.ignore();
    // cin.ignore();
    for (int i = 0; i < h; ++i)
      getline(cin, house[i]);

    vector<int> sx(3, 0);
    vector<int> sy(3, 0);

    vector<int> tx(3, 0);
    vector<int> ty(3, 0);
    for (int i = 0; i < h; ++i) {
      for (int j = 0; j < w; ++j) {
        if (house[i][j] >= 'A' && house[i][j] <= 'C') {
          tx[(house[i][j] - 'A')] = j;
          ty[(house[i][j] - 'A')] = i;
        }
        if (house[i][j] >= 'a' && house[i][j] <= 'c') {
          sx[(house[i][j] - 'a')] = j;
          sy[(house[i][j] - 'a')] = i;
        }
      }
    }

    cout << meetMiddle(sy, sx, ty, tx) << endl;
  }
}