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

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

#define typeof(x) __typeof__(x)
#define bit(x, i) (x & (1 << i))          // select the bit of position i of x
#define lowbit(x) ((x) & ((x) ^ ((x)-1))) // get the lowest bit of x
#define hBit(msb, n)                                                           \\
  asm("bsrl %1,%0"                                                             \\
      : "=r"(msb)                                                              \\
      : "r"(n)) // get the highest bit of x, maybe the fastest
#define max(a, b) (a < b ? b : a)
// #define abs(x) (x<0?(-x):x) // big bug here if "-x" is not surrounded by "()"
#define IN(i, l, r) (l < i && i < r) // the next for are for checking bound
#define LINR(i, l, r) (l <= i && i <= r)
#define LIN(i, l, r) (l <= i && i < r)
#define INR(i, l, r) (l < i && i <= r)
#define F(i, L, R) for (int i = L; i < R; i++) // next four are for "for loops"
#define FIN(i, L, R) for (int i = L; i <= R; i++)
#define FF(i, L, R) for (int i = L; i > R; i--)
#define FFIN(i, L, R) for (int i = L; i >= R; i--)
#define getI(a)                                                                \\
  scanf("%d", &a) // next three are handy ways to get ints, it's also force you
                  // to use '&' sign
#define getII(a, b) scanf("%d%d", &a, &b)
#define getIII(a, b, c) scanf("%d%d%d", &a, &b, &c)
#define g_s(n)                                                                 \\
  int(n);                                                                      \\
  scanf(                                                                       \\
      "%d",                                                                    \\
      &(n)) // handy if the input is right after the definition of a variable
#define g_s2(n, m)                                                             \\
  int(n), (m);                                                                 \\
  scanf("%d %d", &(n), &(m))
#define g_s3(n, m, k)                                                          \\
  int(n), (m), (k);                                                            \\
  scanf("%d %d %d", &(n), &(m), &(k))
#define TESTS                                                                  \\
  g_s(testow);                                                                 \\
  while (testow--) // for multilple cases problems
#define whileZ                                                                 \\
  int T;                                                                       \\
  getI(T);                                                                     \\
  while (T--)                             // the same as above
#define getS(x) scanf("%s", x)            // get a char* string
#define MEM(a, x) memset(a, x, sizeof(a)) // set elements of array to some value
#define char2Int(c) (c - '0')
#define lastEle(vec) vec[vec.size() - 1]
#define SZ(x) ((int)((x).size()))
#define REMAX(a, b) (a) = max((a), (b)) // set a to the maximum of a and b
#define REMIN(a, b) (a) = min((a), (b));
#define FOREACH(i, t)                                                          \\
  for (typeof(t.begin()) i = t.begin(); i != t.end();                          \\
       i++)                           // traverse an STL data structure
#define ALL(c) (c).begin(), (c).end() // handy for function like "sort()"
#define PRESENT(c, x) ((c).find(x) != (c).end())
#define CPRESENT(c, x) (find(ALL(c), x) != (c).end())
#define ll                                                                     \\
  long long // data types used often, but you don't want to type them time by
            // time
#define ull unsigned long long
#define ui unsigned int
#define us unsigned short
#define IOS                                                                    \\
  ios_base::sync_with_stdio(0); // to synchronize the input of cin and scanf
#define INF 1001001001
#define PI 3.1415926535897932384626
// for map, pair
#define mp make_pair
#define fi first
#define se second
// for debug
inline void pisz(int n) { printf("%d\\n", n); }
#define DBG(vari) cerr << #vari << " = " << (vari) << endl;
#define printA(a, L, R) FIN(jk, L, R) cout << a[jk] << (jk == R ? '\\n' : ' ')
#define printV(a) printA(a, 0, a.size() - 1)
#define MAXN 10000
#define sf scanf
#define pf printf
// for vectors
#define pb push_back
typedef int elem_t;
typedef vector<int> vi;
typedef vector<string> vstr;
typedef vector<set<int>> vset;
typedef vector<vi> vvi;
typedef vector<bool> vb;
typedef vector<vector<bool>> vvb;
typedef pair<int, int> ii;
typedef vector<ii> vii;
// directions
const int dr[4] = {-1, 0, 1, 0};
const int dc[4] = {0, -1, 0, 1};
const int drr[8] = {-1, -1, 0, 1, 1, 1, 0, -1};
const int dcc[8] = {0, -1, -1, -1, 0, 1, 1, 1};

const int knr[8] = {1, 2, -1, -2, 1, -2, 2, -1};
const int knc[8] = {2, 1, -2, -1, -2, 1, -1, 2};
template <typename T, typename TT>
ostream &operator<<(ostream &s, pair<T, TT> t) {
  return s << "(" << t.first << "," << t.second << ")";
}
template <typename T> ostream &operator<<(ostream &s, vector<T> t) {
  F(i, 0, SZ(t)) s << t[i] << " ";
  return s;
}

class UnionFind {
private:
  vi rank, p;

public:
  UnionFind(int n) {
    F(i, 0, n) p.pb(i);
    rank.assign(n, 0);
  }

  int findSet(int s) { return (p[s] == s) ? s : (p[s] = findSet(p[s])); }

  bool isSameSet(int i, int j) { return findSet(i) == findSet(j); }

  void unionSet(int i, int j) {
    if (isSameSet(i, j))
      return;

    int x = findSet(i), y = findSet(j);
    if (rank[x] > rank[y])
      p[y] = x;
    else {
      p[x] = y;
      if (rank[x] == rank[y])
        rank[y]++;
    }
  }
};

double x_y(int x1, int y1, int x2, int y2) {
  return sqrt((x1 - x2) * (x1 - x2) + (y1 - y2) * (y1 - y2));
}
queue<ii> q;
vstr track;
int r, c, str, stc, dstr, dstc, vis[1010][1010];
int dis[1010][1010];

bool isval(int i, int j) {
  if (i >= 0 && i < r && j >= 0 && j < c && track[i][j] == '.')
    return true;
  return false;
}

void dfs(int ir, int ic, int val) {
  dis[ir][ic] = val;
  q.push({ir, ic});
  F(i, 0, 4) {
    int nwr = ir + dr[i], nwc = ic + dc[i];
    if (isval(nwr, nwc) && dis[nwr][nwc] > val) {
      dfs(nwr, nwc, val);
    }
  }
}

// int rec(int i,int j){

// if(!isval(i,j))return 1e8;
// if(i==dstr && j==dstc)return 0;
////vis[i][j]=1;

// int &ret=dp[i][j];
// if(ret != -1)return ret;

// int best= 1e8;
// F(k,0,4){
// int nwr= i+dr[k],nwc=j+dc[k];
// if(isval(nwr,nwc)&& !vis[nwr][nwc])best= min(best,rec(nwr,nwc));
//}

// F(k,0,8){
// int nwr= i+knr[k],nwc=j+knc[k];
// if(isval(nwr,nwc) && !vis[nwr][nwc])best = min(best,1+rec(nwr,nwc));
//}
// return ret=best;
//}

int bfs() {

  vis[str][stc] = 1;

  q.push({str, stc});

  F(i, 0, r) { F(j, 0, c) dis[i][j] = 1e8; }
  dis[str][stc] = 0;

  while (!q.empty()) {

    int i = q.front().fi;
    int j = q.front().se;
    q.pop();

    vis[i][j] = 1;
    F(k, 0, 4) {
      int nwr = i + dr[k], nwc = j + dc[k];
      if (isval(nwr, nwc)) {
        if (dis[nwr][nwc] > dis[i][j]) {
          dfs(nwr, nwc, dis[i][j]);
        }
        // else break;
      }
    }

    // F(k,0,8){
    // int nwr=knr[k]+i,nwc=j+knc[k];
    // if(isval(nwr,nwc)&&dis[nwr][nwc]>(dis[i][j]+1)){
    // dis[nwr][nwc] = dis[i][j]+1;
    // q.push({nwr,nwc});
    //}
    //}
    int ivr = i - 2, ivc = j - 2;
    F(nwr, ivr, ivr + 5) {
      int na = 0;
      F(nwc, ivc, ivc + 5) {
        if (isval(nwr, nwc)) {
          if (dis[nwr][nwc] > (dis[i][j] + 1)) {
            dis[nwr][nwc] = dis[i][j] + 1;
            q.push({nwr, nwc});
          }
          // else {
          ////na=1;
          // break;
          //}
        }
      }
      // if(na)break
    }
  }

  return dis[dstr][dstc];
}

int main() {
  // ios::sync_with_stdio(false);
  // cin.tie(nullptr);
  getII(r, c);
  getII(str, stc);
  getII(dstr, dstc);
  str--;
  stc--;
  dstr--;
  dstc--;

  F(i, 0, r) {
    string s;
    cin >> s;
    track.pb(s);
  }

  //	MEM(dp,-1);
  MEM(vis, 0);

  // cout<<rec(str,stc)<<endl;
  int res = bfs();
  if (res > 1e7)
    cout << "-1" << endl;
  else
    cout << res << endl;

  return 0;
}


Error: TLE

Fixed submission:

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

#define typeof(x) __typeof__(x)
#define bit(x, i) (x & (1 << i))          // select the bit of position i of x
#define lowbit(x) ((x) & ((x) ^ ((x)-1))) // get the lowest bit of x
#define hBit(msb, n)                                                           \\
  asm("bsrl %1,%0"                                                             \\
      : "=r"(msb)                                                              \\
      : "r"(n)) // get the highest bit of x, maybe the fastest
#define max(a, b) (a < b ? b : a)
// #define abs(x) (x<0?(-x):x) // big bug here if "-x" is not surrounded by "()"
#define IN(i, l, r) (l < i && i < r) // the next for are for checking bound
#define LINR(i, l, r) (l <= i && i <= r)
#define LIN(i, l, r) (l <= i && i < r)
#define INR(i, l, r) (l < i && i <= r)
#define F(i, L, R) for (int i = L; i < R; i++) // next four are for "for loops"
#define FIN(i, L, R) for (int i = L; i <= R; i++)
#define FF(i, L, R) for (int i = L; i > R; i--)
#define FFIN(i, L, R) for (int i = L; i >= R; i--)
#define getI(a)                                                                \\
  scanf("%d", &a) // next three are handy ways to get ints, it's also force you
                  // to use '&' sign
#define getII(a, b) scanf("%d%d", &a, &b)
#define getIII(a, b, c) scanf("%d%d%d", &a, &b, &c)
#define g_s(n)                                                                 \\
  int(n);                                                                      \\
  scanf(                                                                       \\
      "%d",                                                                    \\
      &(n)) // handy if the input is right after the definition of a variable
#define g_s2(n, m)                                                             \\
  int(n), (m);                                                                 \\
  scanf("%d %d", &(n), &(m))
#define g_s3(n, m, k)                                                          \\
  int(n), (m), (k);                                                            \\
  scanf("%d %d %d", &(n), &(m), &(k))
#define TESTS                                                                  \\
  g_s(testow);                                                                 \\
  while (testow--) // for multilple cases problems
#define whileZ                                                                 \\
  int T;                                                                       \\
  getI(T);                                                                     \\
  while (T--)                             // the same as above
#define getS(x) scanf("%s", x)            // get a char* string
#define MEM(a, x) memset(a, x, sizeof(a)) // set elements of array to some value
#define char2Int(c) (c - '0')
#define lastEle(vec) vec[vec.size() - 1]
#define SZ(x) ((int)((x).size()))
#define REMAX(a, b) (a) = max((a), (b)) // set a to the maximum of a and b
#define REMIN(a, b) (a) = min((a), (b));
#define FOREACH(i, t)                                                          \\
  for (typeof(t.begin()) i = t.begin(); i != t.end();                          \\
       i++)                           // traverse an STL data structure
#define ALL(c) (c).begin(), (c).end() // handy for function like "sort()"
#define PRESENT(c, x) ((c).find(x) != (c).end())
#define CPRESENT(c, x) (find(ALL(c), x) != (c).end())
#define ll                                                                     \\
  long long // data types used often, but you don't want to type them time by
            // time
#define ull unsigned long long
#define ui unsigned int
#define us unsigned short
#define IOS                                                                    \\
  ios_base::sync_with_stdio(0); // to synchronize the input of cin and scanf
#define INF 1001001001
#define PI 3.1415926535897932384626
// for map, pair
#define mp make_pair
#define fi first
#define se second
// for debug
inline void pisz(int n) { printf("%d\\n", n); }
#define DBG(vari) cerr << #vari << " = " << (vari) << endl;
#define printA(a, L, R) FIN(jk, L, R) cout << a[jk] << (jk == R ? '\\n' : ' ')
#define printV(a) printA(a, 0, a.size() - 1)
#define MAXN 10000
#define sf scanf
#define pf printf
// for vectors
#define pb push_back
typedef int elem_t;
typedef vector<int> vi;
typedef vector<string> vstr;
typedef vector<set<int>> vset;
typedef vector<vi> vvi;
typedef vector<bool> vb;
typedef vector<vector<bool>> vvb;
typedef pair<int, int> ii;
typedef vector<ii> vii;
// directions
const int dr[4] = {-1, 0, 1, 0};
const int dc[4] = {0, -1, 0, 1};
const int drr[8] = {-1, -1, 0, 1, 1, 1, 0, -1};
const int dcc[8] = {0, -1, -1, -1, 0, 1, 1, 1};

const int knr[8] = {1, 2, -1, -2, 1, -2, 2, -1};
const int knc[8] = {2, 1, -2, -1, -2, 1, -1, 2};
template <typename T, typename TT>
ostream &operator<<(ostream &s, pair<T, TT> t) {
  return s << "(" << t.first << "," << t.second << ")";
}
template <typename T> ostream &operator<<(ostream &s, vector<T> t) {
  F(i, 0, SZ(t)) s << t[i] << " ";
  return s;
}

class UnionFind {
private:
  vi rank, p;

public:
  UnionFind(int n) {
    F(i, 0, n) p.pb(i);
    rank.assign(n, 0);
  }

  int findSet(int s) { return (p[s] == s) ? s : (p[s] = findSet(p[s])); }

  bool isSameSet(int i, int j) { return findSet(i) == findSet(j); }

  void unionSet(int i, int j) {
    if (isSameSet(i, j))
      return;

    int x = findSet(i), y = findSet(j);
    if (rank[x] > rank[y])
      p[y] = x;
    else {
      p[x] = y;
      if (rank[x] == rank[y])
        rank[y]++;
    }
  }
};

double x_y(int x1, int y1, int x2, int y2) {
  return sqrt((x1 - x2) * (x1 - x2) + (y1 - y2) * (y1 - y2));
}

vstr track;
int r, c, str, stc, dstr, dstc, vis[1010][1010];

bool isval(int i, int j) {
  if (i >= 0 && i < r && j >= 0 && j < c && track[i][j] == '.')
    return true;
  return false;
}

// int rec(int i,int j){

// if(!isval(i,j))return 1e8;
// if(i==dstr && j==dstc)return 0;
////vis[i][j]=1;

// int &ret=dp[i][j];
// if(ret != -1)return ret;

// int best= 1e8;
// F(k,0,4){
// int nwr= i+dr[k],nwc=j+dc[k];
// if(isval(nwr,nwc)&& !vis[nwr][nwc])best= min(best,rec(nwr,nwc));
//}

// F(k,0,8){
// int nwr= i+knr[k],nwc=j+knc[k];
// if(isval(nwr,nwc) && !vis[nwr][nwc])best = min(best,1+rec(nwr,nwc));
//}
// return ret=best;
//}

int bfs() {

  vis[str][stc] = 0;
  queue<ii> q;
  q.push({str, stc});
  int dis[1010][1010];
  F(i, 0, 1010) { F(j, 0, 1010) dis[i][j] = 1e8; }
  dis[str][stc] = 0;

  while (!q.empty()) {

    int i = q.front().fi;
    int j = q.front().se;
    q.pop();

    vis[i][j] = 1;
    F(k, 0, 4) {
      int nwr = i + dr[k], nwc = j + dc[k];
      if (isval(nwr, nwc)) {
        if (dis[nwr][nwc] > dis[i][j]) {
          dis[nwr][nwc] = dis[i][j];
          q.push({nwr, nwc});
        }
        // else break;
      }
    }

    // F(k,0,8){
    // int nwr=knr[k]+i,nwc=j+knc[k];
    // if(isval(nwr,nwc)&&dis[nwr][nwc]>(dis[i][j]+1)){
    // dis[nwr][nwc] = dis[i][j]+1;
    // q.push({nwr,nwc});
    //}
    //}
    int ivr = i - 2, ivc = j - 2;
    F(nwr, ivr, ivr + 5) {
      int na = 0;
      F(nwc, ivc, ivc + 5) {
        if (isval(nwr, nwc)) {
          if (dis[nwr][nwc] > (dis[i][j] + 1)) {
            dis[nwr][nwc] = dis[i][j] + 1;
            q.push({nwr, nwc});
          }
          // else {
          ////na=1;
          // break;
          //}
        }
      }
      // if(na)break
    }
  }

  return dis[dstr][dstc];
}

int main() {
  // ios::sync_with_stdio(false);
  // cin.tie(nullptr);
  getII(r, c);
  getII(str, stc);
  getII(dstr, dstc);
  str--;
  stc--;
  dstr--;
  dstc--;

  F(i, 0, r) {
    string s;
    cin >> s;
    track.pb(s);
  }

  //	MEM(dp,-1);
  MEM(vis, 0);

  // cout<<rec(str,stc)<<endl;
  int res = bfs();
  if (res > 1e7)
    cout << "-1" << endl;
  else
    cout << res << endl;

  return 0;
}