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

#include <bits/stdc++.h>
#define r(i, n) for (int i = 0; i < n; i++)
using namespace std;
typedef pair<int, int> P;
typedef pair<P, P> PP;
typedef pair<int, PP> iPP;
#define F first
#define S second

int h, w;
int dis[31][31][31][31][8];
int dp[31][31][8][8];
int DX[] = {0, 1, 2, 2, 1, 0, -1, -1};
int DY[] = {-1, -1, 0, 1, 2, 2, 1, 0};
int dx[] = {0, 1, 0, -1};
int dy[] = {-1, 0, 1, 0};

string s[55];

void BFS_INIT() {
  r(i, 31) r(j, 31) r(k, 31) r(l, 31) r(q, 8) dis[i][j][k][l][q] = 1e9;
  r(i, h - 1) r(j, w - 1) {
    if (s[i][j] == '*' || s[i][j] == '*' || s[i][j] == '*' ||
        s[i + 1][j + 1] == '*')
      continue;
    set<P> st;
    r(Y, 2) r(X, 2) st.insert(P(i + Y, j + X));
    r(k, 8) {
      int y = i + DY[k];
      int x = j + DX[k];
      if (y < 0 || x < 0 || y >= h || x >= w)
        continue;
      if (s[y][x] == '*')
        continue;
      dis[i][j][y][x][k] = 0;
      queue<P> q;
      q.push(P(y, x));
      // cout<<i<<j<<k<<endl;
      while (!q.empty()) {
        int y = q.front().F;
        int x = q.front().S;
        q.pop();
        r(l, 4) {
          int ny = y + dy[l];
          int nx = x + dx[l];
          if (ny < 0 || nx < 0 || ny >= h || nx >= w)
            continue;
          if (s[ny][nx] == '*')
            continue;
          if (st.count(P(ny, nx)))
            continue;
          if (dis[i][j][ny][nx][k] != 1e9)
            continue;
          dis[i][j][ny][nx][k] = dis[i][j][y][x][k] + 1;
          // cout<<i<<' '<<j<<' '<<ny<<' '<<nx<<' '<<k<<endl;
          q.push(P(ny, nx));
        }
      }
    }
  }
}

void STATE_INIT() {
  int sx1, sx2, sy1, sy2, c = 0, cnt = 0, sx, sy;
  r(i, 31) r(j, 31) r(k, 8) r(l, 8) dp[i][j][k][l] = 1e9;
  r(i, h) r(j, w) {
    if (s[i][j] == '.') {
      if (!c)
        sx1 = j, sy1 = i, c++;
      else
        sx2 = j, sy2 = i;
    }
    if (s[i][j] == 'X' && !cnt) {
      cnt++;
      sx = j;
      sy = i;
    }
  }
  r(i, 8) r(j, 8) {
    int gx1 = sx + DX[i];
    int gy1 = sy + DY[i];
    int gx2 = sx + DX[j];
    int gy2 = sy + DY[j];
    if (gx1 < 0 || gy1 < 0 || gx1 >= w || gy1 >= h)
      continue;
    if (gx2 < 0 || gy2 < 0 || gx2 >= w || gy2 >= h)
      continue;
    // cout<<i<<j<<' '<<dis[sy][sx][sy1][sx1][i]<<'
    // '<<dis[sy][sx][sy2][sx2][j]<<endl;
    if (dis[sy][sx][sy1][sx1][i] == 1e9)
      continue;
    if (dis[sy][sx][sy2][sx2][i] == 1e9)
      continue;
    dp[sy][sx][i][j] = dis[sy][sx][sy1][sx1][i] + dis[sy][sx][sy2][sx2][j];
    dp[sy][sx][i][j] = min(dp[sy][sx][i][j], dp[sy][sx][j][i]);
    dp[sy][sx][j][i] = min(dp[sy][sx][i][j], dp[sy][sx][j][i]);
  }
}

int COST(int y, int x, int a, int b, int A, int B) {
  if (a != A) {
    int Y = y + DY[a];
    int X = x + DX[a];
    return dis[y][x][Y][X][A];
  }
  if (b != B) {
    int Y = y + DY[b];
    int X = x + DX[b];
    return dis[y][x][Y][X][B];
  }
}

void DIJKSTRA() {
  priority_queue<iPP, vector<iPP>, greater<iPP>> q;
  int sx, sy, cnt = 0;
  r(i, h) r(j, w) {
    if (s[i][j] == 'X' && !cnt) {
      cnt++;
      sx = j;
      sy = i;
    }
  }
  r(i, 8) r(j, 8) {
    if (dp[sy][sx][i][j] == 1e9)
      continue;
    // cout<<i<<j<<' '<<dp[sy][sx][i][j]<<endl;
    q.push(iPP(dp[sy][sx][i][j], PP(P(sy, sx), P(i, j))));
  }
  while (!q.empty()) {
    iPP p = q.top();
    q.pop();
    int ky = p.S.F.F;
    int kx = p.S.F.S;
    int a = p.S.S.F;
    int b = p.S.S.S;
    int cost = p.F;
    if (a == b)
      continue;
    // cout<<ky<<' '<<kx<<' '<<a<<' '<<b<<' '<<cost<<endl;
    if (!kx && !ky) {
      cout << cost << endl;
      return;
    }
    if (dp[ky][kx][a][b] < cost)
      continue;
    r(i, 8) {
      int ncost = COST(ky, kx, a, b, i, b) + cost;
      if (dp[ky][kx][i][b] <= ncost)
        continue;
      dp[ky][kx][i][b] = ncost;
      q.push(iPP(ncost, PP(P(ky, kx), P(i, b))));
    }
    r(i, 8) {
      int ncost = COST(ky, kx, a, b, a, i) + cost;
      if (dp[ky][kx][a][i] <= ncost)
        continue;
      dp[ky][kx][a][i] = ncost;
      q.push(iPP(ncost, PP(P(ky, kx), P(a, i))));
    }
    if (a > b)
      swap(a, b);
    if (!((a + 1 == b) && (a % 2 == 0)))
      continue;
    // cout<<a<<' '<<b<<' '<<ky<<kx<<endl;
    if (a == 0)
      ky--, a = 4, b = 5;
    else if (a == 2)
      kx++, a = 6, b = 7;
    else if (a == 4)
      ky++, a = 0, b = 1;
    else if (a == 6)
      kx--, a = 2, b = 3;
    int ncost = cost + 1;
    if (dp[ky][kx][a][b] <= ncost)
      continue;
    dp[ky][kx][a][b] = ncost;
    q.push(iPP(ncost, PP(P(ky, kx), P(a, b))));
  }
  cout << -1 << endl;
}

int main() {
  while (cin >> h >> w, h) {
    r(i, h) cin >> s[i];
    if (s[0][0] == 'X') {
      cout << 0 << endl;
      continue;
    }
    BFS_INIT();
    STATE_INIT();
    DIJKSTRA();
  }
}


Error: MLE

Fixed submission:

#include <bits/stdc++.h>
#define r(i, n) for (int i = 0; i < n; i++)
using namespace std;
typedef pair<int, int> P;
typedef pair<P, P> PP;
typedef pair<int, PP> iPP;
#define F first
#define S second

int h, w;
int dis[51][51][51][51][8];
int dp[51][51][8][8];
int DX[] = {0, 1, 2, 2, 1, 0, -1, -1};
int DY[] = {-1, -1, 0, 1, 2, 2, 1, 0};
int dx[] = {0, 1, 0, -1};
int dy[] = {-1, 0, 1, 0};

string s[55];

void BFS_INIT() {
  r(i, 51) r(j, 51) r(k, 51) r(l, 51) r(q, 8) dis[i][j][k][l][q] = 1e9;
  r(i, h - 1) r(j, w - 1) {
    if (s[i][j] == '*' || s[i][j] == '*' || s[i][j] == '*' ||
        s[i + 1][j + 1] == '*')
      continue;
    set<P> st;
    r(Y, 2) r(X, 2) st.insert(P(i + Y, j + X));
    r(k, 8) {
      int y = i + DY[k];
      int x = j + DX[k];
      if (y < 0 || x < 0 || y >= h || x >= w)
        continue;
      dis[i][j][y][x][k] = 0;
      queue<P> q;
      q.push(P(y, x));
      // cout<<i<<j<<k<<endl;
      while (!q.empty()) {
        int y = q.front().F;
        int x = q.front().S;
        q.pop();
        r(l, 4) {
          int ny = y + dy[l];
          int nx = x + dx[l];
          if (ny < 0 || nx < 0 || ny >= h || nx >= w)
            continue;
          if (s[ny][nx] == '*')
            continue;
          if (st.count(P(ny, nx)))
            continue;
          if (dis[i][j][ny][nx][k] != 1e9)
            continue;
          dis[i][j][ny][nx][k] = dis[i][j][y][x][k] + 1;
          // cout<<i<<' '<<j<<' '<<ny<<' '<<nx<<' '<<k<<endl;
          q.push(P(ny, nx));
        }
      }
    }
  }
}

void STATE_INIT() {
  int sx1, sx2, sy1, sy2, c = 0, cnt = 0, sx, sy;
  r(i, 51) r(j, 51) r(k, 8) r(l, 8) dp[i][j][k][l] = 1e9;
  r(i, h) r(j, w) {
    if (s[i][j] == '.') {
      if (!c)
        sx1 = j, sy1 = i, c++;
      else
        sx2 = j, sy2 = i;
    }
    if (s[i][j] == 'X' && !cnt) {
      cnt++;
      sx = j;
      sy = i;
    }
  }
  r(i, 8) r(j, 8) {
    int gx1 = sx + DX[i];
    int gy1 = sy + DY[i];
    int gx2 = sx + DX[j];
    int gy2 = sy + DY[j];
    if (gx1 < 0 || gy1 < 0 || gx1 >= w || gy1 >= h)
      continue;
    if (gx2 < 0 || gy2 < 0 || gx2 >= w || gy2 >= h)
      continue;
    // cout<<i<<j<<' '<<dis[sy][sx][sy1][sx1][i]<<'
    // '<<dis[sy][sx][sy2][sx2][j]<<endl;
    if (dis[sy][sx][sy1][sx1][i] == 1e9)
      continue;
    if (dis[sy][sx][sy2][sx2][i] == 1e9)
      continue;
    dp[sy][sx][i][j] = dis[sy][sx][sy1][sx1][i] + dis[sy][sx][sy2][sx2][j];
    dp[sy][sx][i][j] = min(dp[sy][sx][i][j], dp[sy][sx][j][i]);
    dp[sy][sx][j][i] = min(dp[sy][sx][i][j], dp[sy][sx][j][i]);
  }
}

int COST(int y, int x, int a, int b, int A, int B) {
  if (a != A) {
    int Y = y + DY[a];
    int X = x + DX[a];
    return dis[y][x][Y][X][A];
  }
  if (b != B) {
    int Y = y + DY[b];
    int X = x + DX[b];
    return dis[y][x][Y][X][B];
  }
}

void DIJKSTRA() {
  priority_queue<iPP, vector<iPP>, greater<iPP>> q;
  int sx, sy, cnt = 0;
  r(i, h) r(j, w) {
    if (s[i][j] == 'X' && !cnt) {
      cnt++;
      sx = j;
      sy = i;
    }
  }
  r(i, 8) r(j, 8) {
    if (dp[sy][sx][i][j] == 1e9)
      continue;
    // cout<<i<<j<<' '<<dp[sy][sx][i][j]<<endl;
    q.push(iPP(dp[sy][sx][i][j], PP(P(sy, sx), P(i, j))));
  }
  while (!q.empty()) {
    iPP p = q.top();
    q.pop();
    int ky = p.S.F.F;
    int kx = p.S.F.S;
    int a = p.S.S.F;
    int b = p.S.S.S;
    int cost = p.F;
    // cout<<ky<<' '<<kx<<' '<<a<<' '<<b<<' '<<cost<<endl;
    if (!kx && !ky) {
      cout << cost << endl;
      return;
    }
    if (dp[ky][kx][a][b] < cost)
      continue;
    r(i, 8) {
      int ncost = COST(ky, kx, a, b, i, b) + cost;
      if (dp[ky][kx][i][b] <= ncost)
        continue;
      dp[ky][kx][i][b] = ncost;
      q.push(iPP(ncost, PP(P(ky, kx), P(i, b))));
    }
    r(i, 8) {
      int ncost = COST(ky, kx, a, b, a, i) + cost;
      if (dp[ky][kx][a][i] <= ncost)
        continue;
      dp[ky][kx][a][i] = ncost;
      q.push(iPP(ncost, PP(P(ky, kx), P(a, i))));
    }
    if (!((a + 1 == b) && (a % 2 == 0)))
      continue;
    // cout<<a<<' '<<b<<' '<<ky<<kx<<endl;
    if (a == 0)
      ky--, a = 4, b = 5;
    else if (a == 2)
      kx++, a = 6, b = 7;
    else if (a == 4)
      ky++, a = 0, b = 1;
    else if (a == 6)
      kx--, a = 2, b = 3;
    int ncost = cost + 1;
    if (dp[ky][kx][a][b] <= ncost)
      continue;
    dp[ky][kx][a][b] = ncost;
    q.push(iPP(ncost, PP(P(ky, kx), P(a, b))));
  }
  cout << -1 << endl;
}

int main() {
  while (cin >> h >> w, h) {
    r(i, h) cin >> s[i];
    BFS_INIT();
    STATE_INIT();
    DIJKSTRA();
  }
}