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

#include <algorithm>
#include <bitset>
#include <climits>
#include <cmath>
#include <functional>
#include <iomanip>
#include <iostream>
#include <list>
#include <map>
#include <queue>
#include <set>
#include <sstream>
#include <vector>
using namespace std;

#define rep(i, n) for (int i = 0; i < n; i++)
#define reps(s, i, n) for (int i = s; i < n; i++)
#define rev(i, n) for (int i = n - 1; i >= 0; i--)
#define skip(i, n, p) for (int i = 0; i < n; i += p)
#define all(a) (a).begin(), (a).end()
#define int64 long long
#define debug cerr << __FILE__ << ":" << __LINE__ << endl;
#define INF 2147483647

struct Init {
  Init() {
    cin.tie(0);
    ios::sync_with_stdio(false);
    cout.precision(20);
    cout << fixed;
    // setw(6) << setfill('0')
  }
} init;

template <typename _Ty>
ostream &operator<<(ostream &ostr, const vector<_Ty> &v) {
  for (int i = 0; i < (int)v.size(); i++) {
    ostr << v[i] << (i + 1 != v.size() ? " " : "");
  }
  return ostr;
}

template <typename _K, typename _V>
ostream &operator<<(ostream &ostr, const map<_K, _V> &v) {
  ostr << "{";
  for (auto iter = v.begin(); iter != v.end(); ++iter) {
    ostr << (*iter).first << ": " << (*iter).second << ", ";
  }
  ostr << "}";
  return ostr;
}

template <typename _K> ostream &operator<<(ostream &ostr, const set<_K> &v) {
  for (auto iter = v.begin(); iter != v.end(); ++iter) {
    ostr << *iter << (iter != v.end() ? " " : "");
  }
  return ostr;
}

template <typename _K, typename _V>
ostream &operator<<(ostream &ostr, const pair<_K, _V> &v) {
  ostr << "(" << v.first << ", " << v.second << ")";
  return ostr;
}

vector<string> split(const string &s, char delim) {
  vector<string> result;
  stringstream ss(s);
  string item;
  while (getline(ss, item, delim)) {
    if (!item.empty()) {
      result.push_back(item);
    }
  }
  return result;
}

template <typename T> class SegmentTree {
private:
  int n;
  vector<T> data;
  function<T(T, T)> operation;
  function<T(T, T)> change;
  T init_value;

public:
  SegmentTree(vector<T> d, function<T(T, T)> _operation,
              function<T(T, T)> _change, T _init_value)
      : operation(_operation), change(_change), init_value(_init_value) {
    n = 1;
    while (n < d.size())
      n *= 2;
    data.resize(n * 2 - 1, init_value);

    rep(i, d.size()) data[data.size() - n + i] = d[i];
    rev(i, data.size() - n) data[i] =
        operation(data[i * 2 + 1], data[i * 2 + 2]);
  }

  void update(int index, T val) {
    index += n - 1;
    data[index] = change(data[index], val);
    while (index != 0) {
      index = (index - 1) / 2;
      data[index] = operation(data[index * 2 + 1], data[index * 2 + 2]);
    }
  }

  T query(int a, int b, int k = 0, int l = 0, int r = -1) {
    if (r < 0)
      r = n;
    if (r <= a || b <= l)
      return init_value;
    if (a <= l && r <= b)
      return data[k];

    T left = query(a, b, k * 2 + 1, l, (l + r) / 2);
    T right = query(a, b, k * 2 + 2, (l + r) / 2, r);

    return operation(left, right);
  }

  T operator[](int index) { return data[index + n - 1]; }
};

int main() {
  int H, W, K;
  cin >> H >> W >> K;
  int s1, s2, e1, e2;
  cin >> s1 >> s2 >> e1 >> e2;
  vector<string> s(H);
  rep(i, H) cin >> s[i];

  queue<pair<int, int>> que;
  que.push(make_pair(s1 - 1, s2 - 1));

  vector<vector<int>> score(H, vector<int>(W, INF));
  score[s1 - 1][s2 - 1] = 0;

  while (!que.empty()) {
    auto p = que.front();
    que.pop();

    reps(1, i, K + 1) {
      if (p.first + i < H) {
        if (s[p.first + i][p.second] == '@')
          break;
        if (score[p.first + i][p.second] < score[p.first][p.second])
          break;
        if (score[p.first + i][p.second] != INF)
          continue;
        que.push(make_pair(p.first + i, p.second));
        score[p.first + i][p.second] = score[p.first][p.second] + 1;
      } else {
        break;
      }
    }

    reps(1, i, K + 1) {
      if (p.first - i >= 0) {
        if (s[p.first - i][p.second] == '@')
          break;
        if (score[p.first - i][p.second] < score[p.first][p.second])
          break;
        if (score[p.first - i][p.second] != INF)
          continue;
        que.push(make_pair(p.first - i, p.second));
        score[p.first - i][p.second] = score[p.first][p.second] + 1;
      } else {
        break;
      }
    }

    reps(1, i, K + 1) {
      if (p.second - i >= 0) {
        if (s[p.first][p.second - i] == '@')
          break;
        if (score[p.first][p.second - i] < score[p.first][p.second])
          break;
        if (score[p.first][p.second - i] != INF)
          continue;
        que.push(make_pair(p.first, p.second - i));
        score[p.first][p.second - i] = score[p.first][p.second] + 1;
      } else {
        break;
      }
    }

    reps(1, i, K + 1) {
      if (p.second + i < W) {
        if (s[p.first][p.second + i] == '@')
          break;
        if (score[p.first][p.second + i] < score[p.first][p.second])
          break;
        if (score[p.first][p.second + i] != INF)
          continue;
        que.push(make_pair(p.first, p.second + i));
        score[p.first][p.second + i] = score[p.first][p.second] + 1;
      } else {
        break;
      }
    }
  }

  // cout << endl;
  // for (auto v : score) cout << v << endl;

  int ans = score[e1 - 1][e2 - 1];
  if (ans == INF) {
    cout << -1 << endl;
  } else {
    cout << ans << endl;
  }
}


Error: TLE

Fixed submission:

#include <algorithm>
#include <bitset>
#include <climits>
#include <cmath>
#include <functional>
#include <iomanip>
#include <iostream>
#include <list>
#include <map>
#include <queue>
#include <set>
#include <sstream>
#include <vector>
using namespace std;

#define rep(i, n) for (int i = 0; i < n; i++)
#define reps(s, i, n) for (int i = s; i < n; i++)
#define rev(i, n) for (int i = n - 1; i >= 0; i--)
#define skip(i, n, p) for (int i = 0; i < n; i += p)
#define all(a) (a).begin(), (a).end()
#define int64 long long
#define debug cerr << __FILE__ << ":" << __LINE__ << endl;
#define INF 2147483647

struct Init {
  Init() {
    cin.tie(0);
    ios::sync_with_stdio(false);
    cout.precision(20);
    cout << fixed;
    // setw(6) << setfill('0')
  }
} init;

template <typename _Ty>
ostream &operator<<(ostream &ostr, const vector<_Ty> &v) {
  for (int i = 0; i < (int)v.size(); i++) {
    ostr << v[i] << (i + 1 != v.size() ? " " : "");
  }
  return ostr;
}

template <typename _K, typename _V>
ostream &operator<<(ostream &ostr, const map<_K, _V> &v) {
  ostr << "{";
  for (auto iter = v.begin(); iter != v.end(); ++iter) {
    ostr << (*iter).first << ": " << (*iter).second << ", ";
  }
  ostr << "}";
  return ostr;
}

template <typename _K> ostream &operator<<(ostream &ostr, const set<_K> &v) {
  for (auto iter = v.begin(); iter != v.end(); ++iter) {
    ostr << *iter << (iter != v.end() ? " " : "");
  }
  return ostr;
}

template <typename _K, typename _V>
ostream &operator<<(ostream &ostr, const pair<_K, _V> &v) {
  ostr << "(" << v.first << ", " << v.second << ")";
  return ostr;
}

vector<string> split(const string &s, char delim) {
  vector<string> result;
  stringstream ss(s);
  string item;
  while (getline(ss, item, delim)) {
    if (!item.empty()) {
      result.push_back(item);
    }
  }
  return result;
}

template <typename T> class SegmentTree {
private:
  int n;
  vector<T> data;
  function<T(T, T)> operation;
  function<T(T, T)> change;
  T init_value;

public:
  SegmentTree(vector<T> d, function<T(T, T)> _operation,
              function<T(T, T)> _change, T _init_value)
      : operation(_operation), change(_change), init_value(_init_value) {
    n = 1;
    while (n < d.size())
      n *= 2;
    data.resize(n * 2 - 1, init_value);

    rep(i, d.size()) data[data.size() - n + i] = d[i];
    rev(i, data.size() - n) data[i] =
        operation(data[i * 2 + 1], data[i * 2 + 2]);
  }

  void update(int index, T val) {
    index += n - 1;
    data[index] = change(data[index], val);
    while (index != 0) {
      index = (index - 1) / 2;
      data[index] = operation(data[index * 2 + 1], data[index * 2 + 2]);
    }
  }

  T query(int a, int b, int k = 0, int l = 0, int r = -1) {
    if (r < 0)
      r = n;
    if (r <= a || b <= l)
      return init_value;
    if (a <= l && r <= b)
      return data[k];

    T left = query(a, b, k * 2 + 1, l, (l + r) / 2);
    T right = query(a, b, k * 2 + 2, (l + r) / 2, r);

    return operation(left, right);
  }

  T operator[](int index) { return data[index + n - 1]; }
};

int main() {
  int H, W, K;
  cin >> H >> W >> K;
  int s1, s2, e1, e2;
  cin >> s1 >> s2 >> e1 >> e2;
  vector<string> s(H);
  rep(i, H) cin >> s[i];

  queue<pair<int, int>> que;
  que.push(make_pair(s1 - 1, s2 - 1));

  vector<vector<int>> score(H, vector<int>(W, INF));
  score[s1 - 1][s2 - 1] = 0;

  while (!que.empty()) {
    auto p = que.front();
    que.pop();

    reps(1, i, K + 1) {
      if (p.first + i < H) {
        if (s[p.first + i][p.second] == '@')
          break;
        if (score[p.first + i][p.second] != INF)
          continue;
        que.push(make_pair(p.first + i, p.second));
        score[p.first + i][p.second] = score[p.first][p.second] + 1;
      } else {
        break;
      }
    }

    reps(1, i, K + 1) {
      if (p.first - i >= 0) {
        if (s[p.first - i][p.second] == '@')
          break;
        if (score[p.first - i][p.second] != INF)
          continue;
        que.push(make_pair(p.first - i, p.second));
        score[p.first - i][p.second] = score[p.first][p.second] + 1;
      } else {
        break;
      }
    }

    reps(1, i, K + 1) {
      if (p.second - i >= 0) {
        if (s[p.first][p.second - i] == '@')
          break;
        if (score[p.first][p.second - i] != INF)
          continue;
        que.push(make_pair(p.first, p.second - i));
        score[p.first][p.second - i] = score[p.first][p.second] + 1;
      } else {
        break;
      }
    }

    reps(1, i, K + 1) {
      if (p.second + i < W) {
        if (s[p.first][p.second + i] == '@')
          break;
        if (score[p.first][p.second + i] != INF)
          continue;
        que.push(make_pair(p.first, p.second + i));
        score[p.first][p.second + i] = score[p.first][p.second] + 1;
      } else {
        break;
      }
    }
  }

  int ans = score[e1 - 1][e2 - 1];
  if (ans == INF) {
    cout << -1 << endl;
  } else {
    cout << ans << endl;
  }
}