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

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

typedef long long ll;
typedef vector<ll> vint;
typedef vector<vector<ll>> vvint;

#define rep(i, n) for (ll i = 0; i < n; i++)
#define repf(i, f, n) for (ll i = f; i < n; i++)
#define repr(i, n) for (ll i = n - 1; i >= 0; i--)
#define mp make_pair
#define mt make_tuple
#define ALL(obj) (obj).begin(), (obj).end()
template <class T> bool chmax(T &a, const T &b) {
  if (a < b) {
    a = b;
    return 1;
  }
  return 0;
}
template <class T> bool chmin(T &a, const T &b) {
  if (b < a) {
    a = b;
    return 1;
  }
  return 0;
}

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

ll h, w, k;

ll x1, x2, Y1, y2;

using P = pair<ll, ll>;
vector<vector<P>> dist[4];

vector<vector<char>> c;

P getDist(ll x, ll y, ll dir) {
  // puts("getDist");
  return dist[dir][x][y];
}

void setDist(ll x, ll y, ll dir, P d) {
  // puts("setDist");
  dist[dir][x][y] = d;
}

int main() {
  cout << fixed << setprecision(10);

  cin >> h >> w >> k;
  cin >> x1 >> Y1;
  cin >> x2 >> y2;

  c.resize(h + 2, vector<char>(w + 2, '@'));
  rep(i, h) rep(j, w) cin >> c[i + 1][j + 1];

  rep(i, 4) dist[i].resize(h + 2, vector<P>(w + 2, make_pair(LLONG_MAX, 0ll)));

  // for(auto row:c){
  //     for(auto e:row) cout<<e; cout<<endl;
  // }

  using T = tuple<P, ll, ll, ll>; // dist, dir, x, y
  priority_queue<T, vector<T>, greater<T>> pq;

  rep(dir, 4) pq.push(make_tuple(make_pair(1ll, -k), dir, x1, Y1));

  while (!pq.empty()) {
    P d;
    ll dir, x, y;
    tie(d, dir, x, y) = pq.top();
    pq.pop();

    // cout<<d.first<<" "<<d.second<<": ";
    // for(auto e:{dir,x,y}) cout<<e<<" "; cout<<endl;

    if (getDist(x, y, dir) <= d)
      continue;
    setDist(x, y, dir, d);

    ll nx, ny;
    nx = x + dx[dir];
    ny = y + dy[dir];

    P nd = d;
    nd.second++;
    if (nd.second > 0) {
      nd.first++;
      nd.second -= k;
    }
    if (c[nx][ny] != '@' and getDist(nx, ny, dir) > nd) {
      pq.push(make_tuple(nd, dir, nx, ny));
    }

    rep(i, 4) {
      if (dir == i)
        continue;
      P nd = d;
      nd.first++;
      nd.second = -k;
      if (getDist(x, y, i) <= nd)
        continue;
      pq.push(make_tuple(nd, i, x, y));
    }
  }

  ll ans = LLONG_MAX;

  rep(i, 4) {
    // cout<<getDist(x2,y2,i)<<endl;
    chmin(ans, getDist(x2, y2, i).first);
  }

  if (ans == LLONG_MAX)
    cout << -1 << endl;
  else
    cout << ans << endl;

  return 0;
}

Error: TLE

Fixed submission:

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

typedef long long ll;
typedef vector<ll> vint;
typedef vector<vector<ll>> vvint;

#define rep(i, n) for (ll i = 0; i < n; i++)
#define repf(i, f, n) for (ll i = f; i < n; i++)
#define repr(i, n) for (ll i = n - 1; i >= 0; i--)
#define mp make_pair
#define mt make_tuple
#define ALL(obj) (obj).begin(), (obj).end()
template <class T> bool chmax(T &a, const T &b) {
  if (a < b) {
    a = b;
    return 1;
  }
  return 0;
}
template <class T> bool chmin(T &a, const T &b) {
  if (b < a) {
    a = b;
    return 1;
  }
  return 0;
}

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

ll h, w, k;

ll x1, x2, Y1, y2;

vvint dist[4];

vector<vector<char>> c;

ll getDist(ll x, ll y, ll dir) {
  // puts("getDist");
  return dist[dir][x][y];
}

void setDist(ll x, ll y, ll dir, ll d) {
  // puts("setDist");
  dist[dir][x][y] = d;
}

int main() {
  cout << fixed << setprecision(10);

  cin >> h >> w >> k;
  cin >> x1 >> Y1;
  cin >> x2 >> y2;

  c.resize(h + 2, vector<char>(w + 2, '@'));
  rep(i, h) rep(j, w) cin >> c[i + 1][j + 1];

  rep(i, 4) dist[i].resize(h + 2, vint(w + 2, LLONG_MAX));

  // for(auto row:c){
  //     for(auto e:row) cout<<e; cout<<endl;
  // }

  using T = tuple<ll, ll, ll, ll>; // dist, dir, x, y
  // priority_queue<T, vector<T>, greater<T>> pq;
  stack<T> pq;

  pq.push(make_tuple(0ll, 0ll, x1, Y1));
  rep(i, 4) setDist(x1, Y1, i, 0);

  while (!pq.empty()) {
    ll d, dir, x, y;
    tie(d, dir, x, y) = pq.top();
    pq.pop();
    // printf("(%ld, %ld)\\n", x, y);

    // for(auto e:{d,dir,x,y}) cout<<e<<" "; cout<<endl;

    // if(getDist(x, y, dir) <= d) continue;
    // bool f = false;
    // rep(dir, 4){
    //     if(getDist(x,y,dir) <= d){
    //         f = true;
    //         break;
    //     }
    // }
    // if(f) continue;
    // rep(dir, 4) setDist(x, y, dir, d);

    rep(i, 4) {
      ll nx, ny;
      nx = x;
      ny = y;
      rep(j, k) {
        nx += dx[i];
        ny += dy[i];
        // printf("(%ld, %ld) (%ld, %ld)\\n", i, j, nx, ny);
        if (c[nx][ny] == '@')
          break;
        if (getDist(nx, ny, i) <= d + 1)
          break;
        pq.push(make_tuple(d + 1, i, nx, ny));
        rep(dir, 4) setDist(nx, ny, dir, d + 1);
      }
    }
  }

  ll ans = LLONG_MAX;

  rep(i, 4) { chmin(ans, getDist(x2, y2, i)); }

  if (ans == LLONG_MAX)
    cout << -1 << endl;
  else
    cout << ans << endl;

  return 0;
}