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

#include <bits/stdc++.h>
using namespace std;
#define F first
#define S second
typedef pair<int, int> P;
typedef pair<P, P> PP;
int n, m, INF = 1 << 29, dxx[4] = {-1, 0, 1, 0}, dyy[4] = {0, -1, 0, 1};
int dx[8] = {-1, -1, 0, 1, 2, 2, 0, 1}, dy[8] = {0, 1, -1, -1, 0, 1, 2, 2};
string s[55];
bool check(int x, int y) { return x >= 0 && x < n && y >= 0 && y < m; }
bool check(int x, int y, int xx, int yy) {
  if (x >= 0 && x < n && y >= 0 && y < m) {
    if (s[x][y] == '*')
      return 0;
    if (x == xx && (y == yy || y == yy + 1))
      return 0;
    if (x == xx + 1 && (y == yy || y == yy + 1))
      return 0;
    return 1;
  }
  return 0;
}

int calc(int sx, int sy, int tx, int ty, int xx, int yy) {
  if (!check(sx, sy, xx, yy) || !check(tx, ty, xx, yy))
    return INF;
  int d[n][m];
  for (int i = 0; i < n; i++)
    for (int j = 0; j < m; j++)
      d[i][j] = INF;
  d[sx][sy] = 0;
  queue<P> que;
  que.push(P(sx, sy));
  while (!que.empty()) {
    P p = que.front();
    que.pop();
    for (int i = 0; i < 4; i++) {
      int x = p.F + dxx[i], y = p.S + dyy[i];
      if (!check(x, y, xx, yy) || d[x][y] <= d[p.F][p.S] + 1)
        continue;
      d[x][y] = d[p.F][p.S] + 1;
      que.push(P(x, y));
    }
  }
  return d[tx][ty];
}

int main() {
  while (cin >> n >> m && n) {
    for (int i = 0; i < n; i++)
      cin >> s[i];
    int d[n][m][4];
    for (int i = 0; i < n; i++)
      for (int j = 0; j < m; j++)
        for (int k = 0; k < 4; k++)
          d[i][j][k] = INF;
    vector<P> v;
    P p = P(-1, -1);
    for (int i = 0; i < n; i++)
      for (int j = 0; j < m; j++) {
        if (s[i][j] == '.')
          v.push_back(P(i, j));
        if (s[i][j] == 'X' && p.F == -1)
          p = P(i, j);
      }
    if (p == P(0, 0)) {
      cout << 0 << endl;
      continue;
    }
    priority_queue<PP, vector<PP>, greater<PP>> que;
    for (int i = 0; i < 4; i++) {
      int b[2] = {0, 1};
      do {
        int cost = calc(v[0].F, v[0].S, p.F + dx[i * 2 + b[0]],
                        p.S + dy[i * 2 + b[0]], p.F, p.S);
        cost += calc(v[1].F, v[1].S, p.F + dx[i * 2 + b[1]],
                     p.S + dy[i * 2 + b[1]], p.F, p.S);
        d[p.F][p.S][i] = min(d[p.F][p.S][i], cost);
      } while (next_permutation(b, b + 2));
      que.push(PP(P(0, i), p));
    }
    while (!que.empty()) {
      PP pp = que.top();
      que.pop();
      int x = pp.S.F, y = pp.S.S, k = pp.F.S, c = pp.F.F;
      if (d[x][y][k] < c)
        continue;
      for (int i = 0; i < 4; i++) {
        int xx = x + dxx[i], yy = y + dyy[i];
        int cost = INF;
        int b[2] = {0, 1};
        do {
          int sum = calc(x + dx[k * 2], y + dy[k * 2], x + dx[i * 2 + b[0]],
                         y + dy[i * 2 + b[0]], x, y);
          sum += calc(x + dx[k * 2 + 1], y + dy[k * 2 + 1],
                      x + dx[i * 2 + b[1]], y + dy[i * 2 + b[1]], x, y);
          cost = min(cost, sum);
        } while (next_permutation(b, b + 2));
        if (!check(xx, yy) || d[xx][yy][(i + 2) % 4] <= d[x][y][k] + cost + 1)
          continue;
        d[xx][yy][(i + 2) % 4] = d[x][y][k] + cost + 1;
        que.push(PP(P(d[xx][yy][(i + 2) % 4], (i + 2) % 4), P(xx, yy)));
      }
    }
    int ans = INF;
    for (int i = 0; i < 4; i++)
      ans = min(ans, d[0][0][i]);
    if (ans == INF)
      ans = -1;
    cout << ans << endl;
  }
  return 0;
}

Error: TLE

Fixed submission:

#include <bits/stdc++.h>
using namespace std;
#define F first
#define S second
typedef pair<int, int> P;
typedef pair<P, P> PP;
int n, m, INF = 1 << 29, dxx[4] = {-1, 0, 1, 0}, dyy[4] = {0, -1, 0, 1};
int dx[8] = {-1, -1, 0, 1, 2, 2, 0, 1}, dy[8] = {0, 1, -1, -1, 0, 1, 2, 2};
string s[55];
bool check(int x, int y) { return x >= 0 && x < n && y >= 0 && y < m; }
bool check(int x, int y, int xx, int yy) {
  if (x >= 0 && x < n && y >= 0 && y < m) {
    if (s[x][y] == '*')
      return 0;
    if (x == xx && (y == yy || y == yy + 1))
      return 0;
    if (x == xx + 1 && (y == yy || y == yy + 1))
      return 0;
    return 1;
  }
  return 0;
}

int calc(int sx, int sy, int tx, int ty, int xx, int yy) {
  if (!check(sx, sy, xx, yy) || !check(tx, ty, xx, yy))
    return INF;
  int d[n][m];
  for (int i = 0; i < n; i++)
    for (int j = 0; j < m; j++)
      d[i][j] = INF;
  d[sx][sy] = 0;
  queue<P> que;
  que.push(P(sx, sy));
  while (!que.empty()) {
    P p = que.front();
    que.pop();
    for (int i = 0; i < 4; i++) {
      int x = p.F + dxx[i], y = p.S + dyy[i];
      if (!check(x, y, xx, yy) || d[x][y] <= d[p.F][p.S] + 1)
        continue;
      d[x][y] = d[p.F][p.S] + 1;
      que.push(P(x, y));
    }
  }
  return d[tx][ty];
}

int main() {
  while (cin >> n >> m && n) {
    for (int i = 0; i < n; i++)
      cin >> s[i];
    int d[n][m][4];
    for (int i = 0; i < n; i++)
      for (int j = 0; j < m; j++)
        for (int k = 0; k < 4; k++)
          d[i][j][k] = INF;
    vector<P> v;
    P p = P(-1, -1);
    for (int i = 0; i < n; i++)
      for (int j = 0; j < m; j++) {
        if (s[i][j] == '.')
          v.push_back(P(i, j));
        if (s[i][j] == 'X' && p.F == -1)
          p = P(i, j);
      }
    if (p == P(0, 0)) {
      cout << 0 << endl;
      continue;
    }
    priority_queue<PP> que;
    for (int i = 0; i < 4; i++) {
      int b[2] = {0, 1};
      do {
        int cost = calc(v[0].F, v[0].S, p.F + dx[i * 2 + b[0]],
                        p.S + dy[i * 2 + b[0]], p.F, p.S);
        cost += calc(v[1].F, v[1].S, p.F + dx[i * 2 + b[1]],
                     p.S + dy[i * 2 + b[1]], p.F, p.S);
        d[p.F][p.S][i] = min(d[p.F][p.S][i], cost);
      } while (next_permutation(b, b + 2));
      que.push(PP(P(0, i), p));
    }
    while (!que.empty()) {
      PP pp = que.top();
      que.pop();
      int x = pp.S.F, y = pp.S.S, k = pp.F.S, c = pp.F.F;
      if (d[x][y][k] < c)
        continue;
      for (int i = 0; i < 4; i++) {
        int xx = x + dxx[i], yy = y + dyy[i];
        int cost = INF;
        int b[2] = {0, 1};
        do {
          int sum = calc(x + dx[k * 2], y + dy[k * 2], x + dx[i * 2 + b[0]],
                         y + dy[i * 2 + b[0]], x, y);
          sum += calc(x + dx[k * 2 + 1], y + dy[k * 2 + 1],
                      x + dx[i * 2 + b[1]], y + dy[i * 2 + b[1]], x, y);
          cost = min(cost, sum);
        } while (next_permutation(b, b + 2));
        if (!check(xx, yy) || d[xx][yy][(i + 2) % 4] <= d[x][y][k] + cost + 1)
          continue;
        d[xx][yy][(i + 2) % 4] = d[x][y][k] + cost + 1;
        que.push(PP(P(d[xx][yy][(i + 2) % 4], (i + 2) % 4), P(xx, yy)));
      }
    }
    int ans = INF;
    for (int i = 0; i < 4; i++)
      ans = min(ans, d[0][0][i]);
    if (ans == INF)
      ans = -1;
    cout << ans << endl;
  }
  return 0;
}