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

#include <bits/stdc++.h>

using namespace std;

#define LOG(...) fprintf(stderr, __VA_ARGS__)
// #define LOG(...)
#define FOR(i, a, b) for (int i = (int)(a); i < (int)(b); ++i)
#define REP(i, n) for (int i = 0; i < (int)(n); ++i)
#define ALL(a) (a).begin(), (a).end()
#define RALL(a) (a).rbegin(), (a).rend()
#define EXIST(s, e) ((s).find(e) != (s).end())
#define SORT(c) sort(ALL(c))
#define RSORT(c) sort(RALL(c))

typedef long long ll;
typedef unsigned long long ull;
typedef vector<bool> vb;
typedef vector<int> vi;
typedef vector<ll> vll;
typedef vector<vb> vvb;
typedef vector<vi> vvi;
typedef vector<vll> vvll;
typedef pair<int, int> pii;
typedef pair<ll, ll> pll;

const int dx[] = {-1, 0, 1, 0}, dy[] = {0, 1, 0, -1};
const int ddx[] = {1, 1, 0, 1}, ddy[] = {1, 0, 1, 1};

bool hwall[51][51], vwall[51][51];
int W, H;
int ix, iy, ox, oy;

int min_steps() {
  queue<pii> que;
  que.push({ix, iy});
  pii sentry = {-1, -1};
  que.push(sentry);
  bool G[50][50] = {};
  G[iy][ix] = true;
  int steps = 0;
  while (!que.empty()) {
    pii p = que.front();
    que.pop();
    int x = p.first, y = p.second;
    if (p == sentry) {
      steps++;
      if (que.empty()) {
        return -1; // unreachable
      }
      que.push(sentry);
      continue;
    }
    if (x == ox && y == oy) {
      return steps;
    }

    REP(i, 4) {
      int sx = x + dx[i], sy = y + dy[i];
      if (0 <= sx && sx < W && 0 <= sy && sy < H) {
        if (i % 2 == 0 && vwall[sy + ddy[i]][sx + ddx[i]])
          continue;
        if (i % 2 == 1 && hwall[sy + ddy[i]][sx + ddx[i]])
          continue;
        if (!G[sy][sx]) {
          G[sy][sx] = true;
          que.push({sx, sy});
        }
      }
    }
  }
}

int max_steps() {
  queue<pii> que;
  que.push({ix, iy});
  // ????????????????????????
  // ??´????????????cost-1???????????????????????¨?????§?????????????????°??§????????????????±????????????¨?????§??????
  int G[50][50];
  fill_n((int *)G, 50 * 50, -1);
  G[iy][ix] = 0;
  while (!que.empty()) {
    pii p = que.front();
    que.pop();
    int x = p.first, y = p.second;
    if (x == ox && y == oy)
      break;

    REP(i, 4) {
      int sx = x + dx[i], sy = y + dy[i];
      if (0 <= sx && sx < W && 0 <= sy && sy < H) {
        if (i % 2 == 0 && vwall[sy + ddy[i]][sx + ddx[i]])
          continue;
        if (i % 2 == 1 && hwall[sy + ddy[i]][sx + ddx[i]])
          continue;
        if (G[sy][sx] == -1) {
          G[sy][sx] = G[y][x] + 1;
          que.push({sx, sy});
        }
      }
    }
  }

  //    for (int y = H-1; y >= 0; y--) {
  //        REP(x, W) {
  //            if (G[y][x] == -1) {
  //                LOG("#");
  //            } else {
  //                if (G[y][x] > (0x7e - 0x30)) {
  //                    LOG("$");
  //                } else {
  //                    LOG("%c", '0' + G[y][x]);
  //                }
  //            }
  //        }
  //        LOG("\\n");
  //    }
  //    LOG("min: %d\\n", G[oy][ox]);

  // ?????????
  bool intersection2[50][50] = {};
  vector<pii> intersection;
  intersection.push_back({ix, iy});
  intersection.push_back({ox, oy});

  while (!que.empty())
    que.pop();
  que.push({ox, oy});
  bool G2[50][50] = {};
  G2[oy][ox] = true;
  while (!que.empty()) {
    pii p = que.front();
    que.pop();
    int x = p.first, y = p.second;
    if (x == ix && y == iy)
      break;
    int inter = 0;
    REP(i, 4) {
      int sx = x + dx[i], sy = y + dy[i];
      if (0 <= sx && sx < W && 0 <= sy && sy < H) {
        if (G[sy][sx] == G[y][x] - 1 || G[sy][sx] == G[y][x] + 1) {
          inter++;
        }
        if (!G2[sy][sx] && G[sy][sx] == G[y][x] - 1) {
          G2[sy][sx] = true;
          que.push({sx, sy});
        }
      }
    }
    if (inter > 1) {
      intersection2[y][x] = true;
      intersection.push_back({x, y});
    }
  }

  //    for (int y = H; y >= 1; y--) {
  //        FOR(x, 1, W+1) {
  //            LOG("%c+", hwall[y][x] ? '-' : ' ');
  //        }
  //        LOG("\\n");
  //        FOR(x, 1, W) {
  //            if (intersection2[y-1][x-1]) {
  //                LOG("#");
  //            } else if (G2[y-1][x-1]) {
  //                LOG(".");
  //            } else {
  //                LOG(" ");
  //            }
  //            LOG("%c", vwall[y][x] ? '|' : ' ');
  //        }
  //        LOG("\\n");
  //    }

  int ma = G[oy][ox];
  for (pii p : intersection) {
    int x = p.first, y = p.second;
    REP(i, 4) {
      if (i % 2 == 0 && !vwall[y + ddy[i]][x + ddx[i]]) {
        vwall[y + ddy[i]][x + ddx[i]] = true;
        ma = max(ma, min_steps());
        vwall[y + ddy[i]][x + ddx[i]] = false;
      }
      if (i % 2 == 1 && !hwall[y + ddy[i]][x + ddx[i]]) {
        hwall[y + ddy[i]][x + ddx[i]] = true;
        ma = max(ma, min_steps());
        hwall[y + ddy[i]][x + ddx[i]] = false;
      }
    }
  }
  //    LOG("max: %d\\n", ma);
  return ma - G[oy][ox];
}

int main() {
  int n;
  cin >> W >> H >> n;
  REP(i, n) {
    int sx, sy, dx, dy;
    cin >> sx >> sy >> dx >> dy;
    while (sx != dx) {
      if (sx < dx) {
        sx++;
        hwall[sy][sx] = true;
      } else if (sx > dx) {
        sx--;
        hwall[sy][sx + 1] = true;
      }
    }
    while (sy != dy) {
      if (sy < dy) {
        sy++;
        vwall[sy][sx] = true;
      } else if (sy > dy) {
        sy--;
        vwall[sy + 1][sx] = true;
      }
    }
  }
  cin >> ix >> iy >> ox >> oy;

  //    for (int y = H+1; y >= 1; y--) {
  //        FOR(x, 1, W+1) {
  //            LOG("%c+", hwall[y][x] ? '-' : ' ');
  //        }
  //        LOG("\\n");
  //        FOR(x, 1, W+1) {
  //            if (x == ix+1 && y == iy+1) {
  //                LOG("S");
  //            } else if (x == ox+1 && y == oy+1) {
  //                LOG("G");
  //            } else {
  //                LOG(" ");
  //            }
  //            LOG("%c", vwall[y][x] ? '|' : ' ');
  //        }
  //        LOG("\\n");
  //    }

  cout << max_steps() << endl;
}

Error: TLE

Fixed submission:

#include <bits/stdc++.h>

using namespace std;

#define LOG(...) fprintf(stderr, __VA_ARGS__)
// #define LOG(...)
#define FOR(i, a, b) for (int i = (int)(a); i < (int)(b); ++i)
#define REP(i, n) for (int i = 0; i < (int)(n); ++i)
#define ALL(a) (a).begin(), (a).end()
#define RALL(a) (a).rbegin(), (a).rend()
#define EXIST(s, e) ((s).find(e) != (s).end())
#define SORT(c) sort(ALL(c))
#define RSORT(c) sort(RALL(c))

typedef long long ll;
typedef unsigned long long ull;
typedef vector<bool> vb;
typedef vector<int> vi;
typedef vector<ll> vll;
typedef vector<vb> vvb;
typedef vector<vi> vvi;
typedef vector<vll> vvll;
typedef pair<int, int> pii;
typedef pair<ll, ll> pll;

const int dx[] = {-1, 0, 1, 0}, dy[] = {0, 1, 0, -1};

bool hwall[50][50], vwall[50][50];
int W, H;
int ix, iy, ox, oy;

int min_steps() {
  queue<pii> que;
  que.push({ix, iy});
  pii sentry = {-1, -1};
  que.push(sentry);
  bool G[50][50] = {};
  G[iy][ix] = true;
  int steps = 0;
  while (!que.empty()) {
    pii p = que.front();
    que.pop();
    int x = p.first, y = p.second;
    if (p == sentry) {
      steps++;
      if (que.empty()) {
        return -1; // unreachable
      }
      que.push(sentry);
      continue;
    }
    if (x == ox && y == oy) {
      return steps;
    }

    REP(i, 4) {
      int sx = x + dx[i], sy = y + dy[i];
      if (0 <= sx && sx < W && 0 <= sy && sy < H) {
        if (i == 0 && vwall[sy][sx])
          continue;
        if (i == 1 && hwall[sy - 1][sx])
          continue;
        if (i == 2 && vwall[sy][sx - 1])
          continue;
        if (i == 3 && hwall[sy][sx])
          continue;
        if (!G[sy][sx]) {
          G[sy][sx] = true;
          que.push({sx, sy});
        }
      }
    }
  }
}

int max_steps() {
  queue<pii> que;
  que.push({ix, iy});
  pii sentry = {-1, -1};
  que.push(sentry);
  // ????????????????????????
  // ??´????????????cost-1???????????????????????¨?????§?????????????????°??§????????????????±????????????¨?????§??????
  int G[50][50];
  fill_n((int *)G, 50 * 50, -1);
  G[iy][ix] = 0;
  while (!que.empty()) {
    pii p = que.front();
    que.pop();
    int x = p.first, y = p.second;
    // ??????????????????????±????????????????????????¨???????????????
    if (p == sentry) {
      if (G[oy][ox] != -1) {
        break;
      }
      que.push(sentry);
    }

    REP(i, 4) {
      int sx = x + dx[i], sy = y + dy[i];
      if (0 <= sx && sx < W && 0 <= sy && sy < H) {
        if (i == 0 && vwall[sy][sx])
          continue;
        if (i == 1 && hwall[sy - 1][sx])
          continue;
        if (i == 2 && vwall[sy][sx - 1])
          continue;
        if (i == 3 && hwall[sy][sx])
          continue;
        if (G[sy][sx] == -1) {
          G[sy][sx] = G[y][x] + 1;
          que.push({sx, sy});
        }
      }
    }
  }

  //    for (int y = H+1; y >= 0; y--) {
  //        REP(x, W+1) {
  //            if (G[y][x] == -1) {
  //                LOG("X");
  //            } else {
  //                LOG("%d", G[y][x]);
  //            }
  //        }
  //        LOG("\\n");
  //    }

  int ma = 0;
  while (!que.empty())
    que.pop();
  que.push({ox, oy});
  while (!que.empty()) {
    pii p = que.front();
    que.pop();
    int x = p.first, y = p.second;
    REP(i, 4) {
      int sx = x + dx[i], sy = y + dy[i];
      if (0 <= sx && sx < W && 0 <= sy && sy < H) {
        if (G[sy][sx] == G[y][x] - 1) {
          if (i == 0) {
            vwall[sy][sx] = true;
            ma = max(ma, min_steps());
            vwall[sy][sx] = false;
          }
          if (i == 1) {
            hwall[sy - 1][sx] = true;
            ma = max(ma, min_steps());
            hwall[sy - 1][sx] = false;
          }
          if (i == 2) {
            hwall[sy][sx - 1] = true;
            ma = max(ma, min_steps());
            vwall[sy][sx - 1] = false;
          }
          if (i == 3) {
            hwall[sy][sx] = true;
            ma = max(ma, min_steps());
            hwall[sy][sx] = false;
          }
          que.push({sx, sy});
        }
      }
    }
  }
  return ma;
}

int main() {
  int n;
  cin >> W >> H >> n;
  REP(i, n) {
    int sx, sy, dx, dy;
    cin >> sx >> sy >> dx >> dy;
    while (sx != dx) {
      if (sx < dx)
        sx++;
      else if (sx > dx)
        sx--;
      hwall[sy - 1][sx - 1] = true;
    }
    while (sy != dy) {
      if (sy < dy)
        sy++;
      else if (sy > dy)
        sy--;
      vwall[sy - 1][sx - 1] = true;
    }
  }
  cin >> ix >> iy >> ox >> oy;

  //    for (int y = H+1; y >= 0; y--) {
  //        REP(x, W+1) {
  //            LOG("%d", hwall[y][x] ? 1 : 0);
  //        }
  //        LOG("\\n");
  //    }
  //    LOG("-----\\n");
  //    for (int y = H+1; y >= 0; y--) {
  //        REP(x, W+1) {
  //            LOG("%d", vwall[y][x] ? 1 : 0);
  //        }
  //        LOG("\\n");
  //    }

  int mi = min_steps();
  int ma = max_steps();
  //    LOG("min/max: %d/%d\\n", mi, ma);
  cout << (ma - mi) << endl;
}