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

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
#define FIO                                                                    \\
  ios_base::sync_with_stdio(0);                                                \\
  cin.tie(0);

const int N = 2e5 + 5, M = 1e6 + 6, OO = 0x3f3f3f3f;
int tc;
int h, w, k;
string grid[M];
int dir[] = {-1, 1, 0, 0};
int dic[] = {0, 0, -1, 1};
int dis[M], directions[M];
// vector<vector<ll> > dis, directions;
bool valid(int r, int c) {
  return r >= 0 && r < h && c >= 0 && c < w && grid[r][c] != '@';
}

int main() {
  int x1, x2, y1, y2;
  scanf("%d %d %d ", &h, &w, &k);
  scanf("%d %d %d %d ", &x1, &y1, &x2, &y2);

  for (int i = 0; i < h; i++) {
    string s;
    getline(cin, s);
    grid[i] = s;
  }
  x1--;
  y1--;
  x2--;
  y2--;
  memset(dis, OO, sizeof dis);
  dis[x1 * w + y1] = 0;
  // directions[x1 * w + y1] = 15;
  queue<pair<ll, ll>> q;
  q.push({x1, y1});
  while (!q.empty()) {
    ll ur = q.front().first, uc = q.front().second;
    // cout<<ur<<" "<<uc<<endl;
    q.pop();
    if (ur == x2 && uc == y2)
      break;
    int ncost = dis[ur * w + uc] + 1;
    // cout<<ur<<" "<<uc<<" "<<dis[ur*w + uc]<<endl;
    for (int i = 0; i < 4; i++) {
      int steps = 1, vr, vc;
      while (steps <= k) {
        vr = ur + (dir[i] * steps);
        vc = uc + (dic[i] * steps);
        int cell = vr * w + vc;
        if (valid(vr, vc)) {
          if (dis[cell] > ncost) {
            dis[cell] = ncost;
            q.push({vr, vc});
          } else if (dis[cell] == ncost) {
            steps++;
            continue;
          } else
            break;
        } else
          break;
        steps++;
      }
    }
  }
  printf("%d", dis[x2 * w + y2] == OO ? -1 : dis[x2 * w + y2]);
  return 0;
}


Error: TLE

Fixed submission:

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
#define FIO                                                                    \\
  ios_base::sync_with_stdio(0);                                                \\
  cin.tie(0);

const int N = 2e5 + 5, M = 1e6 + 6, OO = 0x3f3f3f3f;
int tc;
int h, w, k;
string grid[M];
int dir[] = {-1, 1, 0, 0};
int dic[] = {0, 0, -1, 1};
int dis[M], directions[M];
// vector<vector<ll> > dis, directions;
bool valid(int r, int c) {
  return r >= 0 && r < h && c >= 0 && c < w && grid[r][c] != '@';
}

int main() {
  int x1, x2, y1, y2;
  scanf("%d %d %d ", &h, &w, &k);
  scanf("%d %d %d %d ", &x1, &y1, &x2, &y2);

  for (int i = 0; i < h; i++) {
    string s;
    getline(cin, s);
    grid[i] = s;
  }
  x1--;
  y1--;
  x2--;
  y2--;
  memset(dis, OO, sizeof dis);
  dis[x1 * w + y1] = 0;
  // directions[x1 * w + y1] = 15;
  queue<pair<ll, ll>> q;
  q.push({x1, y1});
  while (!q.empty()) {
    ll ur = q.front().first, uc = q.front().second;
    // cout<<ur<<" "<<uc<<endl;
    q.pop();
    if (ur == x2 && uc == y2)
      break;
    int ncost = dis[ur * w + uc] + 1;
    // cout<<ur<<" "<<uc<<" "<<dis[ur*w + uc]<<endl;
    for (int i = 0; i < 4; i++) {
      int steps = 1, vr, vc;
      while (steps <= k) {
        vr = ur + (dir[i] * steps);
        vc = uc + (dic[i] * steps);
        int cell = vr * w + vc;
        if (valid(vr, vc)) {
          if (dis[cell] > ncost) {
            dis[cell] = ncost;
            q.push({vr, vc});
          } else if (dis[cell] == ncost) {
            steps++;
            continue;
          }
        } else
          break;
        steps++;
      }
    }
  }
  printf("%d", dis[x2 * w + y2] == OO ? -1 : dis[x2 * w + y2]);
  return 0;
}