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

//////// Wizard_in_Maze
// https://atcoder.jp/contests/abc176/tasks/abc176_d
// date: 2020-08-22T21:00:10.587610
// memo:

//<editor-fold desc="my macro">

#include <bits/stdc++.h>

#ifdef LOCAL

#include <my/dump.h>

#else
#define dump(...) 42
#define dumpi(x) 42
#endif

typedef long long ll;
using namespace std;

#define foe(x, a) for (auto &(x) : (a))
#define _overload3(_1, _2, _3, name, ...) name
#define rep(...) _overload3(__VA_ARGS__, _rep3, _rep2, )(__VA_ARGS__)
#define _rep3(i, a, b) for (ll i = a, i##_len = (b); i < i##_len; i++)
#define _rep2(i, n) _rep3(i, 0, n)
#define repd(...) _overload3(__VA_ARGS__, _repd3, _repd2, )(__VA_ARGS__)
#define _repd3(i, a, b) for (ll i = b - 1, i##_len = (a); i >= i##_len; i--)
#define _repd2(i, n) _repd3(i, 0, n)
#define loop(...) _overload3(__VA_ARGS__, , _loop2, _loop1)(__VA_ARGS__)
#define _loop2(i, a) for (ll i = a;; i++)
#define _loop1(i) _loop2(i, 0)

#define all(x) x.begin(), x.end()
#define SIZE(x) ((ll)(x).size())

#define pb(a) push_back(a)
#define mp make_pair
#define F first
#define S second
#define vec vector
#define umap unordered_map
#define uset unordered_set

ll dx[24] = {-2, -2, -2, -2, -2, -1, -1, -1, -1, -1, 0, 0,
             0,  0,  1,  1,  1,  1,  1,  2,  2,  2,  2, 2};
ll dy[24] = {-2, -1, 0,  1,  2, -2, -1, 0,  1,  2, -2, -1,
             1,  2,  -2, -1, 0, 1,  2,  -2, -1, 0, 1,  2};

#define bit(n) (1LL << (n))
#define UNIQUE(v) v.erase(unique(v.begin(), v.end()), v.end());

template <class T> bool chmax(T &a, const T &b) {
  if (a < b) {
    a = b;
    return 1;
  }
  return 0;
}

template <class T> bool chmin(T &a, const T &b) {
  if (b < a) {
    a = b;
    return 1;
  }
  return 0;
}

template <typename T, typename... Args> void ci(T &first, Args &...args) {
  ((cin >> first), ..., (cin >> args)); // C++17
}

template <char Sep, typename T, typename... Args>
void print_seq(const T &first, const Args &...args) {
  ((cout << first), ..., (cout << Sep << args)); // C++17
}

void co() { cout << endl; }

template <typename... Words> void co(Words... words) {
  print_seq<' '>(words...);
  cout << endl;
}

#define coi(x) cout << (x) << " "

#define YES(n) cout << ((n) ? "YES" : "NO") << endl
#define Yes(n) cout << ((n) ? "Yes" : "No") << endl
#define sankou(n, a, b) cout << ((n) ? (#a) : (#b)) << endl

#define asrt(expr...) assert((expr))

//</editor-fold>

#define INF 1e19
#define MOD 1e9 + 7
#define MAXR 1000

bool road[MAXR][MAXR];
int loop_n = 0;
bool checked[MAXR][MAXR] = {false};
bool loop_checked[MAXR][MAXR] = {false}; // 最短経路用
int close_loop[MAXR][MAXR]{-1};
uset<int> uncheck;
ll H, W;
bool changed = false;

int toPosi(int i, int j) { return i * W + j; }
pair<int, int> toXY(int posi) {
  int x = posi / W;
  int y = posi % W;
  return make_pair(x, y);
}

// i,jマスにlabel_iでラベリングをする。再帰的に隣接もラベリング
void recur(int i, int j, int label_i) {
  if (i < 0 || H <= i)
    return;
  if (j < 0 || W <= j)
    return;

  if (road[i][j] == true && checked[i][j] == false) {
    uncheck.insert(toPosi(i, j));
    checked[i][j] = true;
    close_loop[i][j] = label_i;
    recur(i + 1, j, label_i);
    recur(i - 1, j, label_i);
    recur(i, j + 1, label_i);
    recur(i, j - 1, label_i);
  }
}

// ターゲット i,j の 5*5の周りに道があれば、label_i+1でマーク
void recur2(int i, int j, int label_i) {
  rep(dd, 24) {
    int xi = i + dx[dd];
    int xj = j + dy[dd];

    if (xi < 0 || H <= xi)
      continue;
    if (xj < 0 || W <= xj)
      continue;

    if (road[xi][xj] == true && checked[xi][xj] == false) {
      changed = true;
      recur(xi, xj, label_i + 1);
    }
  }
}

void recur3(int label_i) {
  vector<int> buf;
  foe(i, uncheck) buf.push_back(i);
  dump(uncheck);

  uncheck.clear();
  foe(i, buf) {
    if (close_loop[toXY(i).F][toXY(i).S] == label_i) {
      recur2(toXY(i).F, toXY(i).S, label_i);
    }
  }
  dump(uncheck);
}

int solve() {
  ci(H, W);
  rep(i, H) rep(j, W) checked[i][j] = false;
  rep(i, H) rep(j, W) loop_checked[i][j] = false;
  rep(i, H) rep(j, W) close_loop[i][j] = -1;

  ll startx, starty;
  ci(startx, starty);
  startx--;
  starty--;
  ll goalx, goaly;
  ci(goalx, goaly);
  goalx--;
  goaly--;
  //    dump(startx,starty);
  //    dump(goalx,goaly);

  rep(i, H) {
    string s;
    ci(s);
    rep(j, W) {
      if (s[j] == '#') {
        road[i][j] = false;
      } else {
        road[i][j] = true;
      }
      //            dump(road[i][j]);
    }
    //        dump(s);
  }
  //    dump(uncheck);

  // road
  //    rep(i,H) {
  //        rep(j,W){
  //            cout << road[i][j] << " ";
  //        }
  //        cout << endl;
  //    }
  //    cout << endl;

  //     すべての道に閉路のラベリング
  int xi = startx;
  int xj = starty;

  // 1個ラベリング
  if (road[xi][xj] == true && checked[xi][xj] == false) {
    recur(xi, xj, 0);
    loop_n++; // 個数はn+1
  }

  // 一個ラベリングの結果
  //    rep(i,H) {
  //        rep(j,W){
  //            cout << close_loop[i][j] << " ";
  //        }
  //        cout << endl;
  //    }
  //    cout << endl;

  loop(i, 0) {
    changed = false;
    recur3(i);
    if (changed == true)
      continue;
    else
      break;
  }

  // n個ラベリングの結果
  //    rep(i,H) {
  //        rep(j,W){
  //            cout << close_loop[i][j] << " ";
  //        }
  //        cout << endl;
  //    }
  //    cout << endl;

  co(close_loop[goalx][goaly]);

  return 0;
}

int main() {
  // 入力の高速化用のコード
  // ios::sync_with_stdio(false);
  // cin.tie(nullptr);

  solve();
  return 0;
}


Error: TLE

Fixed submission:

//////// Wizard_in_Maze
// https://atcoder.jp/contests/abc176/tasks/abc176_d
// date: 2020-08-22T21:00:10.587610
// memo:

//<editor-fold desc="my macro">

#include <bits/stdc++.h>
#ifdef LOCAL
#include <my/dump.h>
#else
#define dump(...) 42
#define dumpi(x) 42
#endif

typedef long long ll;
using namespace std;

#define foe(x, a) for (auto &(x) : (a))
#define _overload3(_1, _2, _3, name, ...) name
#define rep(...) _overload3(__VA_ARGS__, _rep3, _rep2, )(__VA_ARGS__)
#define _rep3(i, a, b) for (ll i = a, i##_len = (b); i < i##_len; i++)
#define _rep2(i, n) _rep3(i, 0, n)
#define repd(...) _overload3(__VA_ARGS__, _repd3, _repd2, )(__VA_ARGS__)
#define _repd3(i, a, b) for (ll i = b - 1, i##_len = (a); i >= i##_len; i--)
#define _repd2(i, n) _repd3(i, 0, n)
#define loop(...) _overload3(__VA_ARGS__, , _loop2, _loop1)(__VA_ARGS__)
#define _loop2(i, a) for (ll i = a;; i++)
#define _loop1(i) _loop2(i, 0)

#define all(x) x.begin(), x.end()
#define SIZE(x) ((ll)(x).size())

#define pb(a) push_back(a)
#define mp make_pair
#define F first
#define S second
#define vec vector
#define umap unordered_map
#define uset unordered_set

ll dx[24] = {-2, -2, -2, -2, -2, -1, -1, -1, -1, -1, 0, 0,
             0,  0,  1,  1,  1,  1,  1,  2,  2,  2,  2, 2};
ll dy[24] = {-2, -1, 0,  1,  2, -2, -1, 0,  1,  2, -2, -1,
             1,  2,  -2, -1, 0, 1,  2,  -2, -1, 0, 1,  2};

#define bit(n) (1LL << (n))
#define UNIQUE(v) v.erase(unique(v.begin(), v.end()), v.end());

template <class T> bool chmax(T &a, const T &b) {
  if (a < b) {
    a = b;
    return 1;
  }
  return 0;
}
template <class T> bool chmin(T &a, const T &b) {
  if (b < a) {
    a = b;
    return 1;
  }
  return 0;
}

template <typename T, typename... Args> void ci(T &first, Args &...args) {
  ((cin >> first), ..., (cin >> args)); // C++17
}

template <char Sep, typename T, typename... Args>
void print_seq(const T &first, const Args &...args) {
  ((cout << first), ..., (cout << Sep << args)); // C++17
}

void co() { cout << endl; }
template <typename... Words> void co(Words... words) {
  print_seq<' '>(words...);
  cout << endl;
}
#define coi(x) cout << (x) << " "

#define YES(n) cout << ((n) ? "YES" : "NO") << endl
#define Yes(n) cout << ((n) ? "Yes" : "No") << endl
#define sankou(n, a, b) cout << ((n) ? (#a) : (#b)) << endl

#define asrt(expr...) assert((expr))
//</editor-fold>

#define INF 1e19
#define MOD 1e9 + 7
#define MAXR 1000

bool road[MAXR][MAXR];
int loop_n = 0;
bool checked[MAXR][MAXR] = {false};
bool loop_checked[MAXR][MAXR] = {false}; // 最短経路用
int close_loop[MAXR][MAXR]{-1};
ll H, W;

// i,jマスにlabel_iでラベリングをする。再帰的に隣接もラベリング
void recur(int i, int j, int label_i) {
  if (i < 0 || H <= i)
    return;
  if (j < 0 || W <= j)
    return;

  if (road[i][j] == true && checked[i][j] == false) {
    checked[i][j] = true;
    close_loop[i][j] = label_i;
    recur(i + 1, j, label_i);
    recur(i - 1, j, label_i);
    recur(i, j + 1, label_i);
    recur(i, j - 1, label_i);
  }
  return;
}

bool changed = false;
// ターゲット i,j の 5*5の周りに道があれば、label_i+1でマーク
void recur2(int i, int j, int label_i) {
  if (i < 0 || H <= i)
    return;
  if (j < 0 || W <= j)
    return;

  rep(di, 24) {
    int xi = i + dx[di];
    int xj = j + dy[di];

    if (xi < 0 || H <= xi)
      continue;
    if (xj < 0 || W <= xj)
      continue;

    if (road[xi][xj] == true && checked[xi][xj] == false) {
      changed = true;
      recur(xi, xj, label_i + 1);
    }
  }
  return;
}

void recur3(int label_i) {
  rep(i, H) {
    rep(j, W) {
      if (close_loop[i][j] == label_i) {
        recur2(i, j, label_i);
      }
    }
  }
}

// close_loopを作成、nは0始まり。
// void make_closed_loop(int i, int j, int n) {
//    if (road[i][j] == true && checked[i][j] == false) {
//        loop_n ++; //個数はn+1
//        recur(i, j, n);
//    }
//
//    int nxi,nxj;
//    nxj=j+1;
//    if (j>=W) {
//        nxj=0;
//        nxi=i+1;
//    }
//    if (i>=H) {
//        return;
//    }
//    make_closed_loop(nxi,nxj, n+1);
//}

int solve() {
  ci(H, W);
  rep(i, H) rep(j, W) checked[i][j] = false;
  rep(i, H) rep(j, W) loop_checked[i][j] = false;
  rep(i, H) rep(j, W) close_loop[i][j] = -1;

  ll startx, starty;
  ci(startx, starty);
  startx--;
  starty--;
  ll goalx, goaly;
  ci(goalx, goaly);
  goalx--;
  goaly--;

  rep(i, H) {
    string s;
    ci(s);
    rep(j, W) {
      if (s[j] == '#') {
        road[i][j] = false;
      } else {
        road[i][j] = true;
      }
      //            dump(road[i][j]);
    }
    //        dump(s);
  }

  // road
  //    rep(i,H) {
  //        rep(j,W){
  //            cout << road[i][j] << " ";
  //        }
  //        cout << endl;
  //    }
  //    cout << endl;

  //     すべての道に閉路のラベリング
  int xi = startx;
  int xj = starty;

  // 1個ラベリング
  if (road[xi][xj] == true && checked[xi][xj] == false) {
    recur(xi, xj, 0);
    loop_n++; // 個数はn+1
  }

  // 一個ラベリングの結果
  //    rep(i,H) {
  //        rep(j,W){
  //            cout << close_loop[i][j] << " ";
  //        }
  //        cout << endl;
  //    }
  //    cout << endl;

  loop(i, 0) {
    changed = false;
    recur3(i);
    if (changed == true)
      continue;
    else
      break;
  }

  // n個ラベリングの結果
  //    rep(i,H) {
  //        rep(j,W){
  //            cout << close_loop[i][j] << " ";
  //        }
  //        cout << endl;
  //    }
  //    cout << endl;

  co(close_loop[goalx][goaly]);

  return 0;
}

int main() {
  // 入力の高速化用のコード
  // ios::sync_with_stdio(false);
  // cin.tie(nullptr);

  solve();
  return 0;
}