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

/*  -*- coding: utf-8 -*-
 *
 * f.cc: F - Pond Skater
 */

#include <algorithm>
#include <cmath>
#include <complex>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <deque>
#include <functional>
#include <iostream>
#include <list>
#include <map>
#include <numeric>
#include <queue>
#include <set>
#include <stack>
#include <string>
#include <utility>
#include <vector>

using namespace std;

/* constant */

const int MAX_HW = 1000000;
const int dxs[] = {1, 0, -1, 0}, dys[] = {0, -1, 0, 1};
const int INF = 1 << 30;

/* typedef */

typedef queue<int> qi;
typedef set<int> si;
typedef vector<si> vsi;

/* global variables */

char s[MAX_HW + 4];
int ds[MAX_HW], tmp[MAX_HW];
vsi hls, vls;

/* subroutines */

inline int xy2p(int x, int y, int w) { return y * w + x; }
inline void p2xy(int p, int &x, int &y, int w) { x = p % w, y = p / w; }

/* main */

int main() {
  int h, w, k;
  scanf("%d%d%d", &h, &w, &k);
  int hw = h * w, maxhw = max(h, w);

  for (int i = 0; i < maxhw; i++)
    tmp[i] = i;
  for (int y = 0; y < h; y++)
    hls.push_back(si(tmp, tmp + w));
  for (int x = 0; x < w; x++)
    vls.push_back(si(tmp, tmp + h));

  int sy, sx, gy, gx;
  scanf("%d%d%d%d", &sy, &sx, &gy, &gx);
  sy--, sx--, gy--, gx--;
  int st = xy2p(sx, sy, w), gl = xy2p(gx, gy, w);

  for (int y = 0; y < h; y++)
    scanf("%s", s + y * w);
  // puts(s);

  fill(ds, ds + hw, -1);
  ds[st] = 0;
  hls[sy].erase(sx);
  vls[sx].erase(sy);

  qi q;
  q.push(st);

  while (!q.empty()) {
    int u = q.front();
    q.pop();
    int ux, uy;
    p2xy(u, ux, uy, w);
    // printf("(%d,%d)=%d\\n", ux, uy, ds[u]);
    if (u == gl)
      break;

    int vd = ds[u] + 1;

    si &hlu = hls[uy], &vlu = vls[ux];

    // x-k .. x+k
    si::iterator sit0 = hlu.lower_bound(ux), sit1 = sit0;

    while (sit1 != hlu.end()) {
      int v = xy2p(*sit1, uy, w);
      if (*sit1 <= ux + k && s[v] == '.') {
        ds[v] = vd;
        q.push(v);
        vls[*sit1].erase(uy);
        sit1++;
      } else
        break;
    }

    while (sit0 != hlu.begin()) {
      si::iterator sit = sit0;
      sit--;
      int v = xy2p(*sit, uy, w);
      if (*sit >= ux - k && s[v] == '.') {
        ds[v] = vd;
        q.push(v);
        vls[*sit].erase(uy);
        sit0--;
      } else
        break;
    }

    if (sit0 != sit1)
      hlu.erase(sit0, sit1);

    // y-k .. y+k
    sit0 = vlu.lower_bound(uy), sit1 = sit0;

    while (sit1 != vlu.end()) {
      int v = xy2p(ux, *sit1, w);
      if (*sit1 <= uy + k && s[v] == '.') {
        ds[v] = vd;
        q.push(v);
        hls[*sit1].erase(ux);
        sit1++;
      } else
        break;
    }

    while (sit0 != vlu.begin()) {
      si::iterator sit = sit0;
      sit--;
      int v = xy2p(ux, *sit, w);
      if (*sit >= uy - k && s[v] == '.') {
        ds[v] = vd;
        q.push(v);
        hls[*sit].erase(ux);
        sit0--;
      } else
        break;
    }

    if (sit0 != sit1)
      vlu.erase(sit0, sit1);
  }

  printf("%d\\n", (ds[gl] >= INF) ? -1 : ds[gl]);

  // for (int y = 0; y < h; y++) {
  // for (int x = 0; x < w; x++) printf("%3d", ds[xy2p(x, y, w)]);
  // putchar('\\n');
  // }
  return 0;
}


Error: TLE

Fixed submission:

/*  -*- coding: utf-8 -*-
 *
 * f.cc: F - Pond Skater
 */

#include <algorithm>
#include <cmath>
#include <complex>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <deque>
#include <functional>
#include <iostream>
#include <list>
#include <map>
#include <numeric>
#include <queue>
#include <set>
#include <stack>
#include <string>
#include <utility>
#include <vector>

using namespace std;

/* constant */

const int MAX_HW = 1000000;
const int dxs[] = {1, 0, -1, 0}, dys[] = {0, -1, 0, 1};
const int INF = 1 << 30;

/* typedef */

typedef queue<int> qi;

/* global variables */

char s[MAX_HW + 4];
int ds[MAX_HW];

/* subroutines */

inline int xy2p(int x, int y, int w) { return y * w + x; }
inline void p2xy(int p, int &x, int &y, int w) { x = p % w, y = p / w; }

/* main */

int main() {
  int h, w, k;
  scanf("%d%d%d", &h, &w, &k);
  int hw = h * w;

  int sy, sx, gy, gx;
  scanf("%d%d%d%d", &sy, &sx, &gy, &gx);
  sy--, sx--, gy--, gx--;
  int st = xy2p(sx, sy, w), gl = xy2p(gx, gy, w);

  for (int y = 0; y < h; y++)
    scanf("%s", s + y * w);
  // puts(s);

  fill(ds, ds + hw, INF);
  ds[st] = 0;

  qi q;
  q.push(st);

  while (!q.empty()) {
    int u = q.front();
    q.pop();
    if (u == gl)
      break;

    int vd = ds[u] + 1;
    int ux, uy;
    p2xy(u, ux, uy, w);

    for (int di = 0; di < 4; di++)
      for (int i = 1; i <= k; i++) {
        int vx = ux + dxs[di] * i, vy = uy + dys[di] * i;
        int v = xy2p(vx, vy, w);
        if (vx >= 0 && vx < w && vy >= 0 && vy < h && s[v] == '.') {
          if (ds[v] > vd) {
            ds[v] = vd;
            q.push(v);
          }
        } else
          break;
      }
  }

  printf("%d\\n", (ds[gl] >= INF) ? -1 : ds[gl]);
  return 0;
}