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

#include <bits/stdc++.h>
#include <limits.h>

using namespace std;

using vvint_t = vector<vector<int>>;
using vpair_t = vector<pair<int, int>>;

void print(vvint_t &s) {
  int H = s.size();
  int W = s.at(0).size();
  for (int h = 0; h < H; h++) {
    for (int w = 0; w < W; w++) {
      int v = s.at(h).at(w);
      if (v == -1) {
        cout << '#';
      } else if (v != INT_MAX) {
        cout << v;
      } else {
        cout << ' ';
      }
    }
    cout << endl;
  }
}

void print(vpair_t &P) {
  for (auto itr = P.begin(); itr != P.end(); itr++) {
    cout << "(" << itr->first << "," << itr->second << ") ";
  }
  cout << endl;
}

void warp_search(vvint_t &S, vpair_t &P, int h, int w, int v);

void paint(vvint_t &S, vpair_t &P, int h, int w, int v) {

  // (h,w)をvにする
  S.at(h).at(w) = v;
  P.push_back(make_pair(h, w));

  // cout << h << " " << w << endl;
  // print(S);

  // 上下左右の評価
  int c;

  // 左
  c = S.at(h).at(w - 1);
  if (c != -1 && c > v) {
    paint(S, P, h, w - 1, v);
  }

  // 上
  c = S.at(h - 1).at(w);
  if (c != -1 && c > v) {
    paint(S, P, h - 1, w, v);
  }

  // 右
  c = S.at(h).at(w + 1);
  if (c != -1 && c > v) {
    paint(S, P, h, w + 1, v);
  }

  // 下
  c = S.at(h + 1).at(w);
  if (c != -1 && c > v) {
    paint(S, P, h + 1, w, v);
  }

  // ワープ可能箇所を探してペイントする
  // warp_search(S, h, w, v+1);
}

void warp_search(vvint_t &S, vpair_t &P, int h, int w, int v) {

  for (int nh = h - 2; nh <= h + 2; nh++) {
    for (int nw = w - 2; nw <= w + 2; nw++) {
      int c = S.at(nh).at(nw);
      if (c != -1 && c > v) {
        // paint(S, P, nh, nw, v);
        P.push_back(make_pair(nh, nw));
      }
    }
  }
}

int main() {
  int H, W, Ch, Cw, Dh, Dw;

  cin >> H >> W;
  cin >> Ch >> Cw;
  cin >> Dh >> Dw;

  vvint_t S(H + 4, vector<int>(W + 4, -1));

  for (int h = 0; h < H; h++) {
    string t;
    cin >> t;
    for (int w = 0; w < t.size(); w++) {
      if (t[w] == '#') {
        S.at(h + 2).at(w + 2) = -1;
      } else {
        S.at(h + 2).at(w + 2) = INT_MAX;
      }
    }
  }

  // print(S);

  vpair_t P; // paint()で塗りつぶした座標
  vpair_t X; // warp_seaerch()でワープ先が見つかった座標
  int v = 0;
  paint(S, P, Ch + 1, Cw + 1, v);

  while (true) {
    v++;
    for (auto itr = P.begin(); itr != P.end(); itr++) {
      warp_search(S, X, itr->first, itr->second, v);
    }
    if (X.size() == 0) {
      break;
    }
    P.clear();
    for (auto itr = X.begin(); itr != X.end(); itr++) {
      int c = S.at(itr->first).at(itr->second);
      if (c != -1 && c > v) {
        paint(S, P, itr->first, itr->second, v);
      }
    }
    if (P.size() == 0) {
      break;
    }
    X.clear();
  }

  int g = S.at(Dh + 1).at(Dw + 1);
  if (g != INT_MAX) {
    cout << g << endl;
  } else {
    cout << "-1" << endl;
  }

  return 0;
}


Error: TLE

Fixed submission:

#include <bits/stdc++.h>
#include <limits.h>

using namespace std;

using vvint_t = vector<vector<int>>;

void print(vvint_t s) {
  int H = s.size();
  int W = s.at(0).size();
  for (int h = 0; h < H; h++) {
    for (int w = 0; w < W; w++) {
      int v = s.at(h).at(w);
      if (v == -1) {
        cout << '#';
      } else if (v != INT_MAX) {
        cout << v;
      } else {
        cout << ' ';
      }
    }
    cout << endl;
  }
}

static int paint2(vvint_t &S, int h, int w, int v);

// dir  0:左, 1:上, 2:右, 3:下
int warp_search(vvint_t &S, int h, int w, int v, int dir) {

  int Hi, Wi, H, W;
  int r = 0;

  switch (dir) {
  case 0:
    Hi = h - 2;
    H = h + 2;
    Wi = w - 2;
    W = w - 1;
    break;
  case 1:
    Hi = h - 2;
    H = h - 1;
    Wi = w - 2;
    W = w + 2;
    break;
  case 2:
    Hi = h - 2;
    H = h + 2;
    Wi = w + 1;
    W = w + 2;
    break;
  default:
    Hi = h + 1;
    H = h + 2;
    Wi = w - 2;
    W = w + 2;
    break;
  }

  // cout << dir << " " << Hi << ":" << H << ":" << Wi << ":" << W << endl;

  for (int nh = Hi; nh <= H; nh++) {
    for (int nw = Wi; nw <= W; nw++) {
      int c = S.at(nh).at(nw);
      if (c != -1 && c > v) {
        paint2(S, nh, nw, v);
        r++;
      }
    }
  }
  return r;
}

int paint2(vvint_t &S, int h, int w, int v) {

  // (h,w)をvにする
  S.at(h).at(w) = v;
  int r = 1;

  // print(S);
  // cout << v << " h:" << h << " w:" << w << endl;

  // 上下左右の評価
  int c;
  // 左
  c = S.at(h).at(w - 1);
  if (c == -1) { // 壁
    warp_search(S, h, w, v + 1, 0);
  } else if (c > v) {
    paint2(S, h, w - 1, v);
  }

  // 上
  c = S.at(h - 1).at(w);
  if (c == -1) { // 壁
    warp_search(S, h, w, v + 1, 1);
  } else if (c > v) {
    paint2(S, h - 1, w, v);
  }

  // 右
  c = S.at(h).at(w + 1);
  if (c == -1) { // 壁
    warp_search(S, h, w, v + 1, 2);
  } else if (c > v) {
    paint2(S, h, w + 1, v);
  }

  // 下
  c = S.at(h + 1).at(w);
  if (c == -1) { // 壁
    warp_search(S, h, w, v + 1, 3);
  } else if (c > v) {
    paint2(S, h + 1, w, v);
  }

  return r;
}

int main() {
  int H, W, Ch, Cw, Dh, Dw;

  cin >> H >> W;
  cin >> Ch >> Cw;
  cin >> Dh >> Dw;

  vvint_t S(H + 4, vector<int>(W + 4, -1));
  for (int h = 0; h < H; h++) {
    string t;
    cin >> t;
    for (int w = 0; w < t.size(); w++) {
      if (t[w] == '#') {
        S.at(h + 2).at(w + 2) = -1;
      } else {
        S.at(h + 2).at(w + 2) = INT_MAX;
      }
    }
  }
  // print(S);

  paint2(S, Ch + 1, Cw + 1, 0);

  int g = S.at(Dh + 1).at(Dw + 1);
  if (g != INT_MAX) {
    cout << g << endl;
  } else {
    cout << "-1" << endl;
  }

  return 0;
}