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

#pragma GCC optimize("Ofast,unroll-loops")
#pragma GCC target("avx,avx2,fma")

#include <bits/stdc++.h>

using namespace std;

#define pii pair<int, int>
#define fi first
#define se second
#define mp make_pair

const int inf = 1e9;

int n, m, k, xs, ys, xf, yf;

vector<vector<int>> f;
vector<vector<char>> t;
vector<vector<vector<bool>>> vis;

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

bool valid(int x, int y) {
  return (x > 0 && y > 0 && x <= n && y <= m && t[x][y] != '@');
}

signed main() {
  ios::sync_with_stdio(false);
  cin.tie(0);
  cout.tie(0);
  cin >> n >> m >> k >> xs >> ys >> xf >> yf;
  f.assign(n + 1, vector<int>(m + 1, inf));
  vis.assign(n + 1, vector<vector<bool>>(m + 1, vector<bool>(4)));
  t.assign(n + 1, vector<char>(m + 1));

  for (int i = 1; i <= n; ++i) {
    for (int j = 1; j <= m; ++j) {
      cin >> t[i][j];
    }
  }

  // Dijkstra
  queue<pii> q;
  q.push({xs, ys});
  f[xs][ys] = 0;
  while (!q.empty()) {
    auto now = q.front();
    q.pop();
    int x, y;
    tie(x, y) = now;
    // 4 directions
    for (int i = 0; i < 4; ++i) {
      for (int j = 1; j <= k; ++j) {
        int nx = x + j * dx[i], ny = y + j * dy[i];
        if (!valid(nx, ny) || f[nx][ny] <= f[x][y])
          break;
        else if (f[nx][ny] == inf)
          f[nx][ny] = f[x][y] + 1, q.push({nx, ny});
      }
    }
  }
  cout << (f[xf][yf] == inf ? -1 : f[xf][yf]);
}

Error: TLE

Fixed submission:

#pragma GCC optimize("Ofast,unroll-loops")
#pragma GCC target("avx,avx2,fma")

#include <bits/stdc++.h>

using namespace std;

#define pii pair<int, int>
#define item pair<int, pii>
#define fi first
#define se second
#define mp make_pair

const int inf = 1e9;

int n, m, k, xs, ys, xf, yf;

vector<vector<int>> f;
vector<vector<char>> t;
vector<vector<vector<bool>>> vis;

bool valid(int x, int y) {
  return (x > 0 && y > 0 && x <= n && y <= m && t[x][y] != '@');
}

int direct(int dx, int dy) {
  if (dx > 0)
    return 0;
  if (dx < 0)
    return 1;
  if (dy > 0)
    return 2;
  if (dy < 0)
    return 3;
}

signed main() {
  ios::sync_with_stdio(false);
  cin.tie(0);
  cout.tie(0);
  cin >> n >> m >> k >> xs >> ys >> xf >> yf;
  f.assign(n + 1, vector<int>(m + 1, inf));
  vis.assign(n + 1, vector<vector<bool>>(m + 1, vector<bool>(4)));
  t.assign(n + 1, vector<char>(m + 1));

  for (int i = 1; i <= n; ++i) {
    for (int j = 1; j <= m; ++j) {
      cin >> t[i][j];
    }
  }

  // Dijkstra
  priority_queue<item, vector<item>, greater<item>> q;
  q.push({0, {xs, ys}});
  f[xs][ys] = 0;
  while (!q.empty()) {
    auto now = q.top();
    q.pop();
    int d, x, y;
    d = now.fi, x = now.se.fi, y = now.se.se;
    if (d == f[x][y]) {
      // 4 directions
      for (int dx = -1; dx >= -k; --dx) {
        if (valid(x + dx, y)) {
          int dir = direct(x + dx, y);
          if (f[x + dx][y] > f[x][y] + 1 && !vis[x + dx][y][dir]) {
            f[x + dx][y] = f[x][y] + 1;
            vis[x + dx][y][dir] = true;
            q.push({f[x + dx][y], {x + dx, y}});
          }
        } else
          break;
      }
      for (int dx = 1; dx <= k; ++dx) {
        if (valid(x + dx, y)) {
          int dir = direct(x + dx, y);
          if (f[x + dx][y] > f[x][y] + 1 && !vis[x + dx][y][dir]) {
            f[x + dx][y] = f[x][y] + 1;
            vis[x + dx][y][dir] = true;
            q.push({f[x + dx][y], {x + dx, y}});
          }
        } else
          break;
      }
      for (int dy = -1; dy >= -k; --dy) {
        if (valid(x, y + dy)) {
          int dir = direct(x, y + dy);
          if (f[x][y + dy] > f[x][y] + 1 && !vis[x][y + dy][dir]) {
            f[x][y + dy] = f[x][y] + 1;
            vis[x][y + dy][dir] = true;
            q.push({f[x][y + dy], {x, y + dy}});
          }
        } else
          break;
      }
      for (int dy = 1; dy <= k; ++dy) {
        if (valid(x, y + dy)) {
          int dir = direct(x, y + dy);
          if (f[x][y + dy] > f[x][y] + 1 && !vis[x][y + dy][dir]) {
            f[x][y + dy] = f[x][y] + 1;
            vis[x][y + dy][dir] = true;
            q.push({f[x][y + dy], {x, y + dy}});
          }
        } else
          break;
      }
    }
  }
  cout << (f[xf][yf] == inf ? -1 : f[xf][yf]);
}