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

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

#define pb push_back
#define mp make_pair
#define f1 first
#define s2 second

#define fastio                                                                 \\
  ios ::sync_with_stdio(0);                                                    \\
  cin.tie(0);                                                                  \\
  cout.tie(0);
#define debug(x...) cerr << "[" << #x << "]: " << x << "\\n";

typedef long long ll;
typedef long double ld;
typedef pair<int, int> ii;
typedef pair<ll, ll> pl;

ld const PI = 4 * atan((ld)1);

int const N = 3e3 + 3;

int h, w;
char grid[N][N];

int result[N][N];

int moveA[4][2] = {{-1, 0}, {1, 0}, {0, -1}, {0, 1}};
int moveB[20][2] = {{-2, -2}, {-2, -1}, {-2, 0}, {-2, 1}, {-2, 2},
                    {-1, -2}, {-1, -1}, {-1, 1}, {-1, 2}, {0, -2},
                    {0, 2},   {1, -2},  {1, -1}, {1, 1},  {1, 2},
                    {2, -2},  {2, -1},  {2, 0},  {2, 1},  {2, 2}};

bool valid(int r, int c) { return 0 <= r && r < h && 0 <= c && c < w; }

bool wall(int r, int c) {
  for (auto m : moveA) {
    int nr = r + m[0];
    int nc = c + m[1];

    if (valid(nr, nc) && grid[nr][nc] == '#') {
      return true;
    }
  }
  return false;
}

bool blank(int r, int c) {
  for (auto m : moveA) {
    int nr = r + m[0];
    int nc = c + m[1];

    if (valid(nr, nc) && grid[nr][nc] == '.') {
      return true;
    }
  }
  return false;
}

struct cstcmp {
  bool operator()(const ii &lhs, const ii &rhs) {
    return result[lhs.f1][lhs.s2] < result[lhs.f1][lhs.s2];
  }
};

void bfs(int r, int c) {
  memset(result, -1, sizeof(result));

  result[r][c] = 0;
  // priority_queue<ii, vector<ii>, cstcmp> qA; //move A
  // priority_queue<ii, vector<ii>, cstcmp> qB; //move B
  queue<ii> qA;
  queue<ii> qB;

  if (blank(r, c))
    qA.push(mp(r, c));
  if (wall(r, c))
    qB.push(mp(r, c));

  while (!qA.empty() || !qB.empty()) {
    while (!qA.empty()) {
      r = qA.front().f1;
      c = qA.front().s2;

      qA.pop();

      for (auto m : moveA) {
        int nr = r + m[0];
        int nc = c + m[1];

        if (valid(nr, nc) && grid[nr][nc] == '.' &&
            (result[nr][nc] == -1 || result[nr][nc] > result[r][c])) {
          result[nr][nc] = result[r][c];
          if (blank(nr, nc))
            qA.push(mp(nr, nc));
          if (wall(nr, nc))
            qB.push(mp(nr, nc));
        }
      }
    }

    if (!qB.empty()) {
      r = qB.front().f1;
      c = qB.front().s2;
      qB.pop();

      for (auto m : moveB) {
        int nr = r + m[0];
        int nc = c + m[1];

        if (valid(nr, nc) && grid[nr][nc] == '.' &&
            (result[nr][nc] == -1 || result[nr][nc] > result[r][c] + 1)) {
          result[nr][nc] = result[r][c] + 1;
          if (blank(nr, nc))
            qA.push(mp(nr, nc));
          if (wall(nr, nc))
            qB.push(mp(nr, nc));
        }
      }
    }
  }
}

int main() {
  fastio;

  int cx, cy;
  int dx, dy;

  cin >> h >> w;
  cin >> cx >> cy;
  cin >> dx >> dy;

  for (int i = 0; i < h; ++i)
    cin >> grid[i];

  cx--;
  cy--;
  dx--;
  dy--;

  bfs(cx, cy);
  cout << result[dx][dy] << '\\n';

  return 0;
}


Error: TLE

Fixed submission:

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

#define pb push_back
#define mp make_pair
#define f1 first
#define s2 second

#define fastio                                                                 \\
  ios ::sync_with_stdio(0);                                                    \\
  cin.tie(0);                                                                  \\
  cout.tie(0);
#define debug(x...) cerr << "[" << #x << "]: " << x << "\\n";

typedef long long ll;
typedef long double ld;
typedef pair<int, int> ii;
typedef pair<ll, ll> pl;

ld const PI = 4 * atan((ld)1);

int const N = 3e3 + 3;

int h, w;
char grid[N][N];

int result[N][N];

int moveA[4][2] = {{-1, 0}, {1, 0}, {0, -1}, {0, 1}};
int moveB[20][2] = {{-2, -2}, {-2, -1}, {-2, 0}, {-2, 1}, {-2, 2},
                    {-1, -2}, {-1, -1}, {-1, 1}, {-1, 2}, {0, -2},
                    {0, 2},   {1, -2},  {1, -1}, {1, 1},  {1, 2},
                    {2, -2},  {2, -1},  {2, 0},  {2, 1},  {2, 2}};

bool valid(int r, int c) { return 0 <= r && r < h && 0 <= c && c < w; }

bool wall(int r, int c) {
  for (auto m : moveA) {
    int nr = r + m[0];
    int nc = c + m[1];

    if (valid(nr, nc) && grid[nr][nc] == '#') {
      return true;
    }
  }
  return false;
}

bool blank(int r, int c) {
  for (auto m : moveA) {
    int nr = r + m[0];
    int nc = c + m[1];

    if (valid(nr, nc) && grid[nr][nc] == '.') {
      return true;
    }
  }
  return false;
}

struct cstcmp {
  bool operator()(const ii &lhs, const ii &rhs) {
    return result[lhs.f1][lhs.s2] < result[lhs.f1][lhs.s2];
  }
};

void bfs(int r, int c) {
  memset(result, -1, sizeof(result));

  result[r][c] = 0;
  priority_queue<ii, vector<ii>, cstcmp> qA; // move A
  priority_queue<ii, vector<ii>, cstcmp> qB; // move B

  if (blank(r, c))
    qA.push(mp(r, c));
  if (wall(r, c))
    qB.push(mp(r, c));

  while (!qA.empty() || !qB.empty()) {
    while (!qA.empty()) {
      r = qA.top().f1;
      c = qA.top().s2;
      qA.pop();

      for (auto m : moveA) {
        int nr = r + m[0];
        int nc = c + m[1];

        if (valid(nr, nc) && grid[nr][nc] == '.' &&
            (result[nr][nc] == -1 || result[nr][nc] > result[r][c])) {
          result[nr][nc] = result[r][c];
          if (blank(nr, nc))
            qA.push(mp(nr, nc));
          if (wall(nr, nc))
            qB.push(mp(nr, nc));
        }
      }
    }

    if (!qB.empty()) {
      r = qB.top().f1;
      c = qB.top().s2;
      qB.pop();

      for (auto m : moveB) {
        int nr = r + m[0];
        int nc = c + m[1];

        if (valid(nr, nc) && grid[nr][nc] == '.' &&
            (result[nr][nc] == -1 || result[nr][nc] > result[r][c] + 1)) {
          result[nr][nc] = result[r][c] + 1;
          if (blank(nr, nc))
            qA.push(mp(nr, nc));
          if (wall(nr, nc))
            qB.push(mp(nr, nc));
        }
      }
    }
  }
}

int main() {
  fastio;

  int cx, cy;
  int dx, dy;

  cin >> h >> w;
  cin >> cx >> cy;
  cin >> dx >> dy;

  for (int i = 0; i < h; ++i)
    cin >> grid[i];

  cx--;
  cy--;
  dx--;
  dy--;

  bfs(cx, cy);
  cout << result[dx][dy] << '\\n';

  return 0;
}