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


#include <bits/stdc++.h>
using namespace std;

int main() {
  int h, w;
  cin >> h >> w;

  int ch, cw;
  cin >> ch >> cw;

  int dh, dw;
  cin >> dh >> dw;

  vector<vector<string>> map;
  for (int i = 0; i < h; i++) {
    string ch;
    cin >> ch;

    vector<string> row;
    for (int j = 0; j < w; j++) {
      row.push_back(ch.substr(j, 1));
    }
    map.push_back(row);
  }

  vector<vector<int>> wrap(h, vector<int>(w, -1));

  int diz = (h < w) ? w : h;
  unordered_set<int> next;
  unordered_set<int> away;
  next.insert((ch - 1) * diz + cw - 1);
  wrap[ch - 1][cw - 1] = 0;

  while (!next.empty()) {

    while (!next.empty()) {
      unordered_set<int> qp;
      for (auto l = next.begin(); l != next.end(); ++l) {
        int x = (*l) / diz;
        int y = (*l) % diz;
        int c;

        for (int i = -2; i <= 2; i++) {
          for (int j = -2; j <= 2; j++) {
            if (x + i < 0 || x + i >= h || y + j < 0 || y + j >= w ||
                (i == 0 && j == 0) || map[x + i][y + j] != ".") {
              continue;
            }

            if (abs(i) + abs(j) == 1) {
              c = 0;
            } else {
              c = 1;
            }

            if (wrap[x + i][y + j] == -1 ||
                wrap[x + i][y + j] > wrap[x][y] + c) {

              wrap[x + i][y + j] = wrap[x][y] + c;
              if (c == 0) {
                qp.insert((x + i) * diz + y + j);
                away.erase((x + i) * diz + y + j);
              } else {
                away.insert((x + i) * diz + y + j);
              }
            }

            if (wrap[dh - 1][dw - 1] == 0) {
              cout << 0;
              return 0;
            }
          }
        }
      }
      next = qp;
    }
    next = away;
    away.clear();
  }
  cout << wrap[dh - 1][dw - 1];

  return 0;
}


Error: TLE

Fixed submission:


#include <bits/stdc++.h>
using namespace std;

int main() {
  int h, w;
  cin >> h >> w;

  int ch, cw;
  cin >> ch >> cw;

  int dh, dw;
  cin >> dh >> dw;

  vector<vector<string>> map;
  for (int i = 0; i < h; i++) {
    string ch;
    cin >> ch;

    vector<string> row;
    for (int j = 0; j < w; j++) {
      row.push_back(ch.substr(j, 1));
    }
    map.push_back(row);
  }

  vector<vector<int>> wrap(h, vector<int>(w, -1));

  int diz = (h < w) ? w : h;
  unordered_set<int> q;
  q.insert((ch - 1) * diz + cw - 1);
  wrap[ch - 1][cw - 1] = 0;

  while (!q.empty()) {
    unordered_set<int> qp;

    for (auto l = q.begin(); l != q.end(); ++l) {
      int x = (*l) / diz;
      int y = (*l) % diz;
      int c;

      for (int i = -2; i <= 2; i++) {
        for (int j = -2; j <= 2; j++) {
          if (x + i < 0 || x + i >= h || y + j < 0 || y + j >= w ||
              (i == 0 && j == 0) || map[x + i][y + j] != ".") {
            continue;
          }

          if (abs(i) + abs(j) == 1) {
            c = 0;
          } else {
            c = 1;
          }

          if (wrap[x + i][y + j] == -1 || wrap[x + i][y + j] > wrap[x][y] + c) {
            wrap[x + i][y + j] = wrap[x][y] + c;
            qp.insert((x + i) * diz + y + j);
          }

          if (wrap[dh - 1][dw - 1] == 0) {
            cout << 0;
            return 0;
          }
        }
      }
    }

    q = qp;
  }
  cout << wrap[dh - 1][dw - 1];

  return 0;
}