Problem p02644 (C++)

Buggy submission (status: Runtime Error):
#include <bits/stdc++.h>

using namespace std;
constexpr int INF = 1000000000;
constexpr int AREA_MAX = 100010;

char flatGrid[AREA_MAX];
set<int> byRow[AREA_MAX], byCol[AREA_MAX];

int main() {
  int h, w, k;
  scanf("%d %d %d", &h, &w, &k);
  int x1, y1, x2, y2;
  scanf("%d %d %d %d", &x1, &y1, &x2, &y2);
  --x1, --y1, --x2, --y2;
  for (int i = 0; i < h; ++i) {
    scanf("%s", flatGrid + i * w);
  }
  auto getCell = [&h, &w](int i, int j) { return flatGrid[i * w + j]; };
  auto deleteCell = [](int i, int j) {
    byRow[i].erase(j);
    byCol[j].erase(i);
  };
  for (int i = 0; i < h; ++i) {
    for (int j = 0; j < w; ++j) {
      byRow[i].insert(j);
      byCol[j].insert(i);
    }
  }
  vector<vector<int>> dist(h, vector<int>(w, -1));
  queue<pair<int, int>> q;
  q.emplace(x1, y1);
  dist[x1][y1] = 0;
  deleteCell(x1, y1);
  while (!q.empty()) {
    int cx, cy;
    tie(cx, cy) = q.front();
    q.pop();
    //		printf("visit %d %d %d\n", cx, cy, dist[cx][cy]);
    int nx = cx, ny = cy;
    auto updateCell = [&cx, &cy, &q, &deleteCell, &dist](int i, int j) {
      //			printf("updating %d %d from %d %d\n", i, j, cx,
      //cy);
      deleteCell(i, j);
      dist[i][j] = dist[cx][cy] + 1;
      q.emplace(i, j);
    };
    while (true) { // moving cy forward
      auto ncell = byRow[nx].upper_bound(ny);
      if (ncell == byRow[nx].end() || *ncell - cy > k ||
          getCell(nx, *ncell) == '@')
        break;
      ny = *ncell;
      updateCell(nx, ny);
    }
    nx = cx, ny = cy;
    while (true) { // move cx forward
      auto ncell = byCol[ny].upper_bound(nx);
      if (ncell == byCol[ny].end() || *ncell - cx > k ||
          getCell(*ncell, ny) == '@')
        break;
      nx = *ncell;
      updateCell(nx, ny);
    }
    nx = cx, ny = cy;
    while (true) { // move cy backward
      auto ncell = byRow[nx].lower_bound(ny);
      if (ncell == byRow[nx].begin())
        break;
      auto nbcell = prev(ncell, 1);
      if (cy - *nbcell > k || getCell(nx, *nbcell) == '@')
        break;
      ny = *nbcell;
      updateCell(nx, ny);
    }
    nx = cx, ny = cy;
    while (true) { // move cx backward
      auto ncell = byCol[ny].lower_bound(nx);
      if (ncell == byCol[ny].begin())
        break;
      auto nbcell = prev(ncell, 1);
      if (cx - *nbcell > k || getCell(*nbcell, ny) == '@')
        break;
      nx = *nbcell;
      updateCell(nx, ny);
    }
  }
  printf("%d\n", dist[x2][y2]);
  return 0;
}


Fixed submission:
#include <bits/stdc++.h>

using namespace std;
constexpr int INF = 1000000000;
constexpr int AREA_MAX = 1000010;

char flatGrid[AREA_MAX];
set<int> byRow[AREA_MAX], byCol[AREA_MAX];

int main() {
  int h, w, k;
  scanf("%d %d %d", &h, &w, &k);
  int x1, y1, x2, y2;
  scanf("%d %d %d %d", &x1, &y1, &x2, &y2);
  --x1, --y1, --x2, --y2;
  for (int i = 0; i < h; ++i) {
    scanf("%s", flatGrid + i * w);
  }
  auto getCell = [&h, &w](int i, int j) { return flatGrid[i * w + j]; };
  auto deleteCell = [](int i, int j) {
    byRow[i].erase(j);
    byCol[j].erase(i);
  };
  for (int i = 0; i < h; ++i) {
    for (int j = 0; j < w; ++j) {
      byRow[i].insert(j);
      byCol[j].insert(i);
    }
  }
  vector<vector<int>> dist(h, vector<int>(w, -1));
  queue<pair<int, int>> q;
  q.emplace(x1, y1);
  dist[x1][y1] = 0;
  deleteCell(x1, y1);
  while (!q.empty()) {
    int cx, cy;
    tie(cx, cy) = q.front();
    q.pop();
    //		printf("visit %d %d %d\n", cx, cy, dist[cx][cy]);
    int nx = cx, ny = cy;
    auto updateCell = [&cx, &cy, &q, &deleteCell, &dist](int i, int j) {
      //			printf("updating %d %d from %d %d\n", i, j, cx,
      //cy);
      deleteCell(i, j);
      dist[i][j] = dist[cx][cy] + 1;
      q.emplace(i, j);
    };
    while (true) { // moving cy forward
      auto ncell = byRow[nx].upper_bound(ny);
      if (ncell == byRow[nx].end() || *ncell - cy > k ||
          getCell(nx, *ncell) == '@')
        break;
      ny = *ncell;
      updateCell(nx, ny);
    }
    nx = cx, ny = cy;
    while (true) { // move cx forward
      auto ncell = byCol[ny].upper_bound(nx);
      if (ncell == byCol[ny].end() || *ncell - cx > k ||
          getCell(*ncell, ny) == '@')
        break;
      nx = *ncell;
      updateCell(nx, ny);
    }
    nx = cx, ny = cy;
    while (true) { // move cy backward
      auto ncell = byRow[nx].lower_bound(ny);
      if (ncell == byRow[nx].begin())
        break;
      auto nbcell = prev(ncell, 1);
      if (cy - *nbcell > k || getCell(nx, *nbcell) == '@')
        break;
      ny = *nbcell;
      updateCell(nx, ny);
    }
    nx = cx, ny = cy;
    while (true) { // move cx backward
      auto ncell = byCol[ny].lower_bound(nx);
      if (ncell == byCol[ny].begin())
        break;
      auto nbcell = prev(ncell, 1);
      if (cx - *nbcell > k || getCell(*nbcell, ny) == '@')
        break;
      nx = *nbcell;
      updateCell(nx, ny);
    }
  }
  printf("%d\n", dist[x2][y2]);
  return 0;
}