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

#pragma GCC optimize("O3")
#include <bits/stdc++.h>
using namespace std;

#define pb push_back
#define mp make_pair
#define fs first
#define se second
#define pi 2 * acos(0)
#define PI 3.14159265358979323846264338

typedef long long ll;
typedef unsigned long long ull;
typedef pair<int, int> pii;
typedef pair<ll, ll> pll;

const int N = 100010;
const int MX = 123456;
const int mod = (int)1e9 + 7;
const int base = 97;
const ull BS1 = 10000019ULL;
const int INF = (1 << 29);

template <class T> inline void fastScan(T &x) {
  register char c = getchar();
  int neg = 0;
  x = 0;
  for (; (c < 48 || c > 57) && (c != '-'); c = getchar())
    ;
  if (c == '-') {
    neg = 1;
    c = getchar();
  }
  for (; c > 47 && c < 58; c = getchar()) {
    x = (x << 1) + (x << 3) + c - 48;
  }
  if (neg)
    x = -x;
}

// OrderedSet
// #include <ext/pb_ds/assoc_container.hpp>
// #include <ext/pb_ds/tree_policy.hpp>
// using namespace __gnu_pbds;
// template < typename T > using ordered_set = tree < T, null_type, greater < T
// >, rb_tree_tag, tree_order_statistics_node_update >;

// typedef uint64_t hash_t;
// mt19937_64 rng(chrono::steady_clock::now().time_since_epoch().count());
// const int HASH_COUNT = 2;
// const hash_t HASH_P = (uint32_t)-13337;
// uniform_int_distribution<hash_t> MULT_DIST(0.25 * HASH_P, 0.75 * HASH_P);
// const hash_t HASH_MULT[HASH_COUNT] = {MULT_DIST(rng), MULT_DIST(rng)};

int fx[] = {+1, -1, 0, 0};
int fy[] = {0, 0, +1, -1};

int H, W, K;

int sx, sy;
int ex, ey;

char s[N * 10];

struct Node {
  int x, y, cost;
  int mov;
};

vector<string> grid;
vector<vector<vector<int>>> dist, cnt;

int isValid(int x, int y) {
  if (x < 0 || y < 0)
    return 0;
  if (x >= H || y >= W)
    return 0;
  if (grid[x][y] != '.')
    return 0;
  return 1;
}

int bfs() {
  dist.resize(H, vector<vector<int>>(W, vector<int>(5, INF)));
  cnt.resize(H, vector<vector<int>>(W, vector<int>(5, INF)));
  queue<Node> Q;
  for (int i = 0; i < 5; i++) {
    dist[sx][sy][i] = 0;
    cnt[sx][sy][i] = 0;
  }
  for (int i = 0; i < 1; i++) {
    Node tmp;
    tmp.x = sx;
    tmp.y = sy;
    tmp.cost = 0;
    tmp.mov = 4;
    Q.push(tmp);
  }
  while (!Q.empty()) {
    Node u = Q.front();
    Q.pop();
    for (int i = 0; i < 4; i++) {
      int x = u.x + fx[i], y = u.y + fy[i];
      if (isValid(x, y)) {
        if (u.mov == i) {
          u.cost = cnt[u.x][u.y][u.mov];
          int ext = (u.cost < K) ? 0 : 1;

          if (dist[u.x][u.y][u.mov] + ext < dist[x][y][i]) {
            dist[x][y][i] = dist[u.x][u.y][u.mov] + ext;
            cnt[x][y][i] = (ext > 0) ? 1 : u.cost + 1;
            Node tmp;
            tmp.x = x;
            tmp.y = y;
            tmp.mov = i;
            tmp.cost = cnt[x][y][i];
            Q.push(tmp);
          } else if (dist[u.x][u.y][u.mov] + ext == dist[x][y][i]) {
            int ncnt = (ext == 0) ? (u.cost + 1) : 1;
            if (ncnt < cnt[x][y][i]) {
              cnt[x][y][i] = ncnt;
              Node tmp;
              tmp.x = x;
              tmp.y = y;
              tmp.mov = i;
              tmp.cost = cnt[x][y][i];
              Q.push(tmp);
            }
          }

        } else {
          if (dist[u.x][u.y][u.mov] + 1 < dist[x][y][i]) {
            dist[x][y][i] = dist[u.x][u.y][u.mov] + 1;
            cnt[x][y][i] = 1;
            Node tmp;
            tmp.x = x;
            tmp.y = y;
            tmp.mov = i;
            tmp.cost = cnt[x][y][i];
            Q.push(tmp);
          } else if (dist[u.x][u.y][u.mov] + 1 == dist[x][y][i]) {
            if (cnt[x][y][i] > 1) {
              cnt[x][y][i] = 1;
              Node tmp;
              tmp.x = x;
              tmp.y = y;
              tmp.mov = i;
              tmp.cost = cnt[x][y][i];
              Q.push(tmp);
            }
          }
        }
      }
    }
  }
  int ans = INF;
  for (int i = 0; i < 5; i++) {
    ans = min(ans, dist[ex][ey][i]);
  }
  if (ans == INF)
    ans = -1;
  return ans;
}

int main() {
  fastScan(H);
  fastScan(W);
  fastScan(K);
  fastScan(sx);
  fastScan(sy);
  fastScan(ex);
  fastScan(ey);
  for (int i = 0; i < H; i++) {
    scanf("%s", s);
    string str = s;
    grid.pb(str);
  }
  sx--;
  sy--;
  ex--;
  ey--;
  printf("%d\\n", bfs());
}

/*
10 10 4
2 10 5 5
.....@...@
.@........
@..@.@...@
..@......@
..........
.....@....
..@.......
..........
@@........
.@..@...@@
*/

/*
2 7 2
2 7 2 1
....@.@
.@.....
*/


Error: TLE

Fixed submission:

#pragma GCC optimize("O3")
#include <bits/stdc++.h>
using namespace std;

#define pb push_back
#define mp make_pair
#define fs first
#define se second
#define pi 2 * acos(0)
#define PI 3.14159265358979323846264338

typedef long long ll;
typedef unsigned long long ull;
typedef pair<int, int> pii;
typedef pair<ll, ll> pll;

const int N = 100010;
const int MX = 123456;
const int mod = (int)1e9 + 7;
const int base = 97;
const ull BS1 = 10000019ULL;
const int INF = (1 << 29);

template <class T> inline void fastScan(T &x) {
  register char c = getchar();
  int neg = 0;
  x = 0;
  for (; (c < 48 || c > 57) && (c != '-'); c = getchar())
    ;
  if (c == '-') {
    neg = 1;
    c = getchar();
  }
  for (; c > 47 && c < 58; c = getchar()) {
    x = (x << 1) + (x << 3) + c - 48;
  }
  if (neg)
    x = -x;
}

// OrderedSet
// #include <ext/pb_ds/assoc_container.hpp>
// #include <ext/pb_ds/tree_policy.hpp>
// using namespace __gnu_pbds;
// template < typename T > using ordered_set = tree < T, null_type, greater < T
// >, rb_tree_tag, tree_order_statistics_node_update >;

// typedef uint64_t hash_t;
// mt19937_64 rng(chrono::steady_clock::now().time_since_epoch().count());
// const int HASH_COUNT = 2;
// const hash_t HASH_P = (uint32_t)-13337;
// uniform_int_distribution<hash_t> MULT_DIST(0.25 * HASH_P, 0.75 * HASH_P);
// const hash_t HASH_MULT[HASH_COUNT] = {MULT_DIST(rng), MULT_DIST(rng)};

int fx[] = {+1, -1, 0, 0};
int fy[] = {0, 0, +1, -1};

int H, W, K;

int sx, sy;
int ex, ey;

char s[N * 10];

struct Node {
  int x, y, cost;
  int mov;
};

vector<string> grid;
vector<vector<vector<int>>> dist, has;

int isValid(int x, int y) {
  if (x < 0 || y < 0)
    return 0;
  if (x >= H || y >= W)
    return 0;
  if (grid[x][y] != '.')
    return 0;
  return 1;
}

int bfs() {
  dist.resize(H, vector<vector<int>>(W, vector<int>(5, INF)));
  has.resize(H, vector<vector<int>>(W, vector<int>(5, 0)));
  queue<Node> Q;
  for (int i = 0; i < 5; i++) {
    dist[sx][sy][i] = 0;
  }
  for (int i = 0; i < 1; i++) {
    Node tmp;
    tmp.x = sx;
    tmp.y = sy;
    tmp.cost = 0;
    tmp.mov = 4;
    Q.push(tmp);
    has[sx][sy][4] = 1;
  }
  while (!Q.empty()) {
    Node u = Q.front();
    has[u.x][u.y][u.mov] = 0;
    Q.pop();
    for (int i = 0; i < 4; i++) {
      int x = u.x + fx[i], y = u.y + fy[i];
      if (isValid(x, y)) {
        int ext = 0;
        if (i != u.mov)
          ext = 1;
        if (u.cost >= K)
          ext = 1;
        if (dist[u.x][u.y][u.mov] + ext <= dist[x][y][i]) {
          // cout << u.x << " " << u.y << " " << u.cost << " " << u.mov << '\\n';
          // cout << x << " " << y << '\\n';
          dist[x][y][i] = dist[u.x][u.y][u.mov] + ext;
          // cout << "update : " << dist[x][y][i] << '\\n';
          Node tmp;
          tmp.x = x;
          tmp.y = y;
          tmp.mov = i;
          tmp.cost = (ext == 0) ? u.cost + 1 : 1;
          if (has[tmp.x][tmp.y][tmp.mov] == 0)
            Q.push(tmp);
        }
      }
    }
  }
  int ans = INF;
  for (int i = 0; i < 5; i++) {
    ans = min(ans, dist[ex][ey][i]);
  }
  if (ans == INF)
    ans = -1;
  return ans;
}

int main() {
  fastScan(H);
  fastScan(W);
  fastScan(K);
  fastScan(sx);
  fastScan(sy);
  fastScan(ex);
  fastScan(ey);
  for (int i = 0; i < H; i++) {
    scanf("%s", s);
    string str = s;
    grid.pb(str);
  }
  sx--;
  sy--;
  ex--;
  ey--;
  printf("%d\\n", bfs());
}

/*
10 10 4
2 10 5 5
.....@...@
.@........
@..@.@...@
..@......@
..........
.....@....
..@.......
..........
@@........
.@..@...@@
*/

/*
2 7 2
2 7 2 1
....@.@
.@.....
*/