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

#include <bits/stdc++.h>
using namespace std;
typedef pair<int, int> P;
typedef pair<int, P> PP;

int dy[] = {-1, 0, 1, 0};
int dx[] = {0, 1, 0, -1};

int ey[] = {-1, -1, 0, 1, 2, 2, 1, 0};
int ex[] = {0, 1, 2, 2, 1, 0, -1, -1};

int H, W;
char t[50][50];
int sy, sx;
int py0, px0, py1, px1;

int d[50][50];

int calc(int gy, int gx, int sy, int sx, int ty, int tx, bool flg = false) {
  for (int i = 0; i < H; i++)
    for (int j = 0; j < W; j++)
      d[i][j] = 1e8;
  d[sy][sx] = 0;

  queue<int> qy, qx;
  qy.push(sy);
  qx.push(sx);
  while (!qy.empty()) {
    int y = qy.front();
    qy.pop();
    int x = qx.front();
    qx.pop();
    if (y == ty && x == tx)
      break;
    for (int i = 0; i < 4; i++) {
      int ny = y + dy[i];
      int nx = x + dx[i];
      if (ny < 0 || nx < 0)
        continue;
      if (ny >= H || nx >= W)
        continue;
      if (t[ny][nx] == '*')
        continue;
      if (gy <= ny && ny < gy + 2 && gx <= nx && nx < gx + 2)
        continue;
      if (d[ny][nx] > d[y][x] + 1) {
        d[ny][nx] = d[y][x] + 1;
        qy.push(ny);
        qx.push(nx);
      }
    }
  }

  return d[ty][tx];
}

int dd[50][50][4];
int solve(int sy, int sx, int sd) {
  for (int i = 0; i < H; i++)
    for (int j = 0; j < W; j++)
      for (int k = 0; k < 4; k++)
        dd[i][j][k] = 1e8;

  dd[sy][sx][sd] = 0;
  priority_queue<PP, vector<PP>, greater<PP>> Q;
  Q.push(PP(0, P(sy * 50 + sx, sd)));

  while (!Q.empty()) {
    PP pp = Q.top();
    Q.pop();
    int y = pp.second.first / 50;
    int x = pp.second.first % 50;
    int dir = pp.second.second;
    if (y == 0 && x == 0)
      return dd[y][x][dir];
    if (pp.first > dd[y][x][dir])
      continue;

    for (int i = 0; i < 4; i++) {
      int ncost = dd[y][x][dir];
      int ay = y + ey[i * 2], ax = x + ex[i * 2];
      int by = y + ey[i * 2 + 1], bx = x + ex[i * 2 + 1];
      int flg = (dir + 2) % 4;
      int Ay = y + ey[flg * 2], Ax = x + ex[flg * 2];
      int By = y + ey[flg * 2 + 1], Bx = x + ex[flg * 2 + 1];
      int ny = y + dy[i], nx = x + dx[i];
      if (ay < 0 || ax < 0 || ay >= H || ax >= W)
        continue;
      if (by < 0 || bx < 0 || by >= H || bx >= W)
        continue;
      if (t[ay][ax] == '*' || t[by][bx] == '*')
        continue;

      ncost += min(calc(y, x, ay, ax, Ay, Ax) + calc(y, x, by, bx, By, Bx),
                   calc(y, x, ay, ax, By, Bx) + calc(y, x, by, bx, Ay, Ax));

      ncost++;
      if (dd[ny][nx][i] > ncost) {
        dd[ny][nx][i] = ncost;
        Q.push(PP(ncost, P(ny * 50 + nx, i)));
      }
    }
  }
  return 1e8;
}

int main() {
  while (1) {
    cin >> H >> W;
    if (H == 0 && W == 0)
      break;

    sy = sx = -1;
    py0 = px0 = -1;
    py1 = px1 = -1;

    for (int i = 0; i < H; i++) {
      for (int j = 0; j < W; j++) {
        cin >> t[i][j];
        if (t[i][j] == 'X' && sy == -1 && sx == -1) {
          sy = i;
          sx = j;
        }
        if (t[i][j] == '.') {
          py0 = py1;
          px0 = px1;
          py1 = i;
          px1 = j;
        }
      }
    }

    int ans = 1e9;
    if (sy == 0 && sx == 0)
      ans = 0;

    for (int i = 0; i < 4; i++) {
      int ay = sy + ey[i * 2], ax = sx + ex[i * 2];
      int by = sy + ey[i * 2 + 1], bx = sx + ex[i * 2 + 1];
      if (ay < 0 || ax < 0 || by < 0 || bx < 0)
        continue;
      if (ay >= H || ax >= W || by >= H || bx >= W)
        continue;
      if (t[ay][ax] == '*' || t[by][bx] == '*')
        continue;
      int cost =
          min(calc(sy, sx, py0, px0, ay, ax) + calc(sy, sx, py1, px1, by, bx),
              calc(sy, sx, py0, px0, by, bx) + calc(sy, sx, py1, px1, ay, ax));

      ans = min(ans, cost + solve(sy, sx, (i + 2) % 4));
    }
    if (ans >= 1e8)
      ans = -1;
    cout << ans << endl;
  }
  return 0;
}

Error: TLE

Fixed submission:

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

int dy[] = {-1, 0, 1, 0};
int dx[] = {0, 1, 0, -1};

int ey[] = {-1, -1, 0, 1, 2, 2, 1, 0};
int ex[] = {0, 1, 2, 2, 1, 0, -1, -1};

int H, W;
char t[50][50];
int sy, sx;
int py0, px0, py1, px1;

int d[50][50];

int calc(int gy, int gx, int sy, int sx, int ty, int tx, bool flg = false) {

  int cc = 0;
  for (int i = 0; i < H; i++) {
    for (int j = 0; j < W; j++) {
      d[i][j] = 1e8;
      if (abs(sy - i) <= 3 && abs(sx - j) <= 3 && t[i][j] != '*')
        cc++;
    }
  }

  d[sy][sx] = 0;
  queue<int> qy, qx;
  qy.push(sy);
  qx.push(sx);
  while (!qy.empty()) {
    int y = qy.front();
    qy.pop();
    int x = qx.front();
    qx.pop();
    if (abs(y - sy) <= 3 && abs(x - sx) <= 3)
      cc--;
    if (flg && cc == 0)
      break;

    for (int i = 0; i < 4; i++) {
      int ny = y + dy[i];
      int nx = x + dx[i];
      if (ny < 0 || nx < 0)
        continue;
      if (ny >= H || nx >= W)
        continue;
      if (t[ny][nx] == '*')
        continue;
      if (gy <= ny && ny < gy + 2 && gx <= nx && nx < gx + 2)
        continue;
      if (d[ny][nx] > d[y][x] + 1) {
        d[ny][nx] = d[y][x] + 1;
        qy.push(ny);
        qx.push(nx);
      }
    }
  }

  return d[ty][tx];
}

int dd[50][50][4];
int solve(int sy, int sx, int sd, int d[50][50][4] = dd) {

  fill((int *)d[0], (int *)d[50], 1e8);
  d[sy][sx][sd] = 0;
  queue<int> qy, qx, qd;
  qy.push(sy);
  qx.push(sx);
  qd.push(sd);
  while (!qy.empty()) {
    int y = qy.front();
    qy.pop();
    int x = qx.front();
    qx.pop();
    int dir = qd.front();
    qd.pop();
    if (y == 0 && x == 0)
      return d[y][x][dir];
    for (int i = 0; i < 4; i++) {
      int ncost = d[y][x][dir];
      int ay = y + ey[i * 2], ax = x + ex[i * 2];
      int by = y + ey[i * 2 + 1], bx = x + ex[i * 2 + 1];
      int flg = (dir + 2) % 4;
      int Ay = y + ey[flg * 2], Ax = x + ex[flg * 2];
      int By = y + ey[flg * 2 + 1], Bx = x + ex[flg * 2 + 1];
      int ny = y + dy[i], nx = x + dx[i];
      if (ay < 0 || ax < 0 || ay >= H || ax >= W)
        continue;
      if (by < 0 || bx < 0 || by >= H || bx >= W)
        continue;
      if (t[ay][ax] == '*' || t[by][bx] == '*')
        continue;
      ncost += min(
          calc(y, x, ay, ax, Ay, Ax, true) + calc(y, x, by, bx, By, Bx, true),
          calc(y, x, ay, ax, By, Bx, true) + calc(y, x, by, bx, Ay, Ax, true));
      ncost++;
      if (d[ny][nx][i] > ncost) {
        d[ny][nx][i] = ncost;
        qy.push(ny);
        qx.push(nx);
        qd.push(i);
      }
    }
  }
  return 1e8;
}

int main() {
  while (1) {
    cin >> H >> W;
    if (H == 0 && W == 0)
      break;

    sy = sx = -1;
    py0 = px0 = -1;
    py1 = px1 = -1;

    for (int i = 0; i < H; i++) {
      for (int j = 0; j < W; j++) {
        cin >> t[i][j];
        if (t[i][j] == 'X' && sy == -1 && sx == -1) {
          sy = i;
          sx = j;
        }
        if (t[i][j] == '.') {
          py0 = py1;
          px0 = px1;
          py1 = i;
          px1 = j;
        }
      }
    }

    int ans = 1e9;
    if (sy == 0 && sx == 0)
      ans = 0;

    for (int i = 0; i < 4; i++) {
      int ay = sy + ey[i * 2], ax = sx + ex[i * 2];
      int by = sy + ey[i * 2 + 1], bx = sx + ex[i * 2 + 1];
      if (ay < 0 || ax < 0 || by < 0 || bx < 0)
        continue;
      if (ay >= H || ax >= W || by >= H || bx >= W)
        continue;
      if (t[ay][ax] == '*' || t[by][bx] == '*')
        continue;
      int cost =
          min(calc(sx, sy, py0, px0, ay, ax) + calc(sx, sy, py1, px1, by, bx),
              calc(sx, sy, py0, px0, by, bx) + calc(sx, sy, py1, px1, ay, ax));

      //      cout<<i<<' '<<cost<<endl;
      ans = min(ans, cost + solve(sy, sx, i));
    }
    if (ans >= 1e8)
      ans = -1;
    cout << ans << endl;
  }
  return 0;
}