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

#include <bits/stdc++.h>
using namespace std;
using ll = long long;
constexpr ll MOD = 1000000007;
#define REP(i, n) for (ll i = 0; i < (n); i++)
#define REP2(i, x, n) for (ll i = x; i < (n); i++)
const long long INF = numeric_limits<long long>::max();
template <class T> inline bool chmin(T &a, T b) {
  if (a > b) {
    a = b;
    return true;
  }
  return false;
}
template <class T> inline bool chmax(T &a, T b) {
  if (a < b) {
    a = b;
    return true;
  }
  return false;
}
vector<ll> getNums(ll N) {
  vector<ll> num(N);
  REP(i, N) { cin >> num[i]; }
  return num;
}

struct Position {
  ll x;
  ll y;

  bool Within(ll x, ll y) const {
    if (this->x < 0)
      return false;
    if (this->y < 0)
      return false;
    if (this->x >= x)
      return false;
    if (this->y >= y)
      return false;
    return true;
  }

  friend Position operator+(const Position &lhs, const Position &rhs) {
    return Position{lhs.x + rhs.x, lhs.y + rhs.y};
  }

  friend ostream &operator<<(ostream &os, const Position &pos) {
#ifdef SOURCE_TEST
    os << pos.x << "," << pos.y;
#endif
    return os;
  }

  template <class TData> TData &GetValueFrom(vector<vector<TData>> &vec) const {
    return vec[x][y];
  }

  char &GetValueFrom(vector<string> &vec) const { return vec[x][y]; }
};
vector<string> field;
Position start;
Position goal;
ll H, W;

void debugMap() {
#ifdef SOURCE_TEST

  cout << "mapList" << endl;
  for (ll i = 0; i < field.size(); ++i) {
    for (ll j = 0; j < field[i].length(); ++j) {
      if (i == start.x && j == start.y) {
        cout << 'S';
      } else if (i == goal.x && j == goal.y) {
        cout << 'G';
      } else {
        cout << field[i][j];
      }
    }
    cout << endl;
  }
#endif
}

vector<vector<ll>> warpList;
void debugWarp() {
#ifdef SOURCE_TEST

  cout << "warpList" << endl;
  for (ll i = 0; i < warpList.size(); ++i) {
    for (ll j = 0; j < warpList[i].size(); ++j) {
      cout << std::setw(2) << warpList[i][j];
    }
    cout << endl;
  }
#endif
}

bool isOverOk(const Position &pos, ll value) {
  return pos.GetValueFrom(warpList) == -1;
}
void setWalking(const Position &pos, ll value);
void setWarpValue(const Position &pos, ll value) {
  for (ll i = -2; i <= 2; ++i) {
    for (ll j = -2; j <= 2; ++j) {
      if (i == 0 && j == 0)
        continue;

      Position p = pos + Position{i, j};
      if (!p.Within(H, W))
        continue;
      if (p.GetValueFrom(field) == '#')
        continue;
      if (isOverOk(p, value)) {
        p.GetValueFrom(warpList) = value;
      }
    }
  }
#ifdef SOURCE_TEST
  cout << "setWarpCase" << value << "-----" << endl;
#endif
  debugWarp();
}
void setWalkValue(const Position &pos, ll value) {
  if (!pos.Within(H, W))
    return;
  if (pos.GetValueFrom(field) != '#' && isOverOk(pos, value)) {
    pos.GetValueFrom(warpList) = value;
    setWalking(pos, value);
  }
}
void setWalking(const Position &pos, ll value) {
  setWalkValue({pos.x + 1, pos.y}, value);
  setWalkValue({pos.x - 1, pos.y}, value);
  setWalkValue({pos.x, pos.y + 1}, value);
  setWalkValue({pos.x, pos.y - 1}, value);
}

void funcWalk(const Position &pos, ll value) {
  setWalking(pos, value);
#ifdef SOURCE_TEST
  cout << "setWalkEnd" << value << "-----" << endl;
  debugWarp();
#endif

  for (ll i = 0; i < H; ++i) {
    for (ll j = 0; j < W; ++j) {
      if (warpList[i][j] == value) {
        setWarpValue({i, j}, value + 1);
      }
    }
  }

#ifdef SOURCE_TEST
  cout << "warped-----" << endl;
#endif

  for (ll i = 0; i < H; ++i) {
    for (ll j = 0; j < W; ++j) {
      Position pos{i, j};
      if (!pos.Within(H, W))
        continue;
      if (warpList[i][j] == value + 1) {
        funcWalk({i, j}, value + 1);
      }
    }
  }
}

int main() {
  cin >> H >> W;

  cin >> start.x >> start.y;
  start.x--;
  start.y--;
  cin >> goal.x >> goal.y;
  goal.x--;
  goal.y--;

  field.resize(H);
  warpList.resize(H);
  for (ll i = 0; i < H; ++i) {
    cin >> field[i];
    warpList[i] = vector<ll>(W, -1);
  }
  start.GetValueFrom(warpList) = 0;

  debugMap();
  debugWarp();

  // funcWalk(start, 0);

  {
    deque<pair<Position, ll>> queues;
    queues.push_back({start, 0});
    while (!queues.empty()) {
      ll thisValue = queues.front().second;
      vector<Position> setPositions;
      while (!queues.empty()) {
        auto v = queues.front();
        queues.pop_front();
        setPositions.push_back(v.first);
        vector<Position> directions = {{-1, 0}, {1, 0}, {0, -1}, {0, 1}};
        for (const auto d : directions) {
          auto pos = v.first + d;
          if (pos.Within(H, W) && pos.GetValueFrom(field) != '#') {
            auto &value = pos.GetValueFrom(warpList);

            if (value == -1 || value > v.second) {
              value = v.second;
              setPositions.push_back(pos);
              queues.push_front({pos, v.second});
            }
          }
        }
        debugWarp();
      }

      ll nextValue = thisValue + 1;
      for (auto position : setPositions) {
        for (ll i = -2; i <= 2; ++i) {
          for (ll j = -2; j <= 2; ++j) {
            auto p = position + Position{i, j};
            if (!p.Within(H, W))
              continue;
            if (p.GetValueFrom(field) == '#')
              continue;
            auto &v = p.GetValueFrom(warpList);
            if (v == -1 || v > nextValue) {
              v = nextValue;
              queues.push_back({p, nextValue});
            }
          }
        }
      }
    }
  }
#ifdef SOURCE_TEST
  cout << "before ans-----" << endl;
#endif
  debugWarp();

  cout << goal.GetValueFrom(warpList) << endl;

  return 0;
}

Error: TLE

Fixed submission:

#include <bits/stdc++.h>
using namespace std;
using ll = long long;
constexpr ll MOD = 1000000007;
#define REP(i, n) for (ll i = 0; i < (n); i++)
#define REP2(i, x, n) for (ll i = x; i < (n); i++)
const long long INF = numeric_limits<long long>::max();
template <class T> inline bool chmin(T &a, T b) {
  if (a > b) {
    a = b;
    return true;
  }
  return false;
}
template <class T> inline bool chmax(T &a, T b) {
  if (a < b) {
    a = b;
    return true;
  }
  return false;
}
vector<ll> getNums(ll N) {
  vector<ll> num(N);
  REP(i, N) { cin >> num[i]; }
  return num;
}

vector<string> field;
pair<ll, ll> start;
pair<ll, ll> goal;
ll H, W;
void debugMap() {
#ifdef SOURCE_TEST

  cout << "mapList" << endl;
  for (ll i = 0; i < field.size(); ++i) {
    for (ll j = 0; j < field[i].length(); ++j) {
      if (i == start.first && j == start.second) {
        cout << 'S';
      } else if (i == goal.first && j == goal.second) {
        cout << 'G';
      } else {
        cout << field[i][j];
      }
    }
    cout << endl;
  }
#endif
}

vector<vector<ll>> warpList;
void debugWarp() {
#ifdef SOURCE_TEST

  cout << "warpList" << endl;
  for (ll i = 0; i < warpList.size(); ++i) {
    for (ll j = 0; j < warpList[i].size(); ++j) {
      cout << std::setw(2) << warpList[i][j];
    }
    cout << endl;
  }
#endif
}
bool isBoundary(const pair<ll, ll> &pos) {
  if (pos.first < 0)
    return false;
  if (pos.second < 0)
    return false;
  if (pos.first >= H)
    return false;
  if (pos.second >= W)
    return false;
  return true;
}
bool isOverOk(const pair<ll, ll> &pos, ll value) {
  return warpList[pos.first][pos.second] ==
         -1; // || warpList[pos.first][pos.second] > value;
}
void setWalking(const pair<ll, ll> &pos, ll value);
void setWarpValue(const pair<ll, ll> &pos, ll value) {
  for (ll i = -2; i <= 2; ++i) {
    for (ll j = -2; j <= 2; ++j) {
      if (i == 0 && j == 0)
        continue;

      pair<ll, ll> p = {pos.first + i, pos.second + j};
      if (!isBoundary(p))
        continue;
      if (field[p.first][p.second] == '#')
        continue;
      if (isOverOk(p, value)) {
        warpList[p.first][p.second] = value;
      }
    }
  }
#ifdef SOURCE_TEST
  cout << "setWarpCase" << value << "-----" << endl;
#endif
  debugWarp();
}
void setWalkValue(const pair<ll, ll> &beforePos, const pair<ll, ll> &pos,
                  ll value) {
  if (!isBoundary(pos))
    return;
  if (field[pos.first][pos.second] != '#' && isOverOk(pos, value)) {
    warpList[pos.first][pos.second] = value;
    setWalking(pos, value);
  }
}
void setWalking(const pair<ll, ll> &pos, ll value) {
  setWalkValue(pos, {pos.first + 1, pos.second}, value);
  setWalkValue(pos, {pos.first - 1, pos.second}, value);
  setWalkValue(pos, {pos.first, pos.second + 1}, value);
  setWalkValue(pos, {pos.first, pos.second - 1}, value);
}
void funcWalk(const pair<ll, ll> &pos, ll value) {
  setWalking(pos, value);
#ifdef SOURCE_TEST
  cout << "setWalkEnd" << value << "-----" << endl;
  debugWarp();
#endif

  for (ll i = 0; i < H; ++i) {
    for (ll j = 0; j < W; ++j) {
      if (warpList[i][j] == value) {
        setWarpValue({i, j}, value + 1);
      }
    }
  }

#ifdef SOURCE_TEST
  cout << "warped-----" << endl;
#endif

  for (ll i = 0; i < H; ++i) {
    for (ll j = 0; j < W; ++j) {
      if (!isBoundary({i, j}))
        continue;
      if (warpList[i][j] == value + 1) {
        funcWalk({i, j}, value + 1);
      }
    }
  }
}

int main() {
  cin >> H >> W;

  cin >> start.first >> start.second;
  start.first--;
  start.second--;
  cin >> goal.first >> goal.second;
  goal.first--;
  goal.second--;

  field.resize(H);
  warpList.resize(H);
  for (ll i = 0; i < H; ++i) {
    cin >> field[i];
    warpList[i] = vector<ll>(W, -1);
  }
  warpList[start.first][start.second] = 0;

  debugMap();
  debugWarp();

  funcWalk(start, 0);
#ifdef SOURCE_TEST
  cout << "before ans-----" << endl;
#endif
  debugWarp();

  cout << warpList[goal.first][goal.second] << endl;

  return 0;
}