Problem p03053 (C++)

Buggy submission (status: Time Limit Exceeded):
#include <bits/stdc++.h>
using namespace std;
#define INF 3000
#define INFF 9223372036854775807
#define ll long long
#define REP(i, n) for (int i = 0; i < n; i++)
#define REPP(i, m, n) for (int i = m; i < n; i++)
#define ALL(N) (N.begin(), N.end())
#define de cout << "debug" << endl;
#define push_back pb
template <class T> inline bool chmax(T &a, T b) {
  if (a < b) {
    a = b;
    return 1;
  }
  return 0;
}
template <class T> inline bool chmin(T &a, T b) {
  if (a > b) {
    a = b;
    return 1;
  }
  return 0;
}

int main() {
  cin.tie(0);
  ios::sync_with_stdio(false);
  int H, W;
  cin >> H >> W;
  char A[H][W];
  for (int i = 1; i <= H; i++) { // 後々のために1-indexにする
    for (int j = 1; j <= W; j++) {
      cin >> A[i][j];
    }
  }
  int D[1010][1010] = {};
  int ans = 0;
  for (int i = 0; i < 1002; i++) {
    // 盤外にINFを代入して、範囲外の参照に対処する
    D[0][i] = D[i][0] = D[H + 1][i] = D[i][W + 1] = INF;
  }
  for (int i = 1; i <= H; i++) {
    for (int j = 1; j <= W; j++) {
      if (A[i][j] == '#') { // #スタートだから０を代入
        D[i][j] = 0;
      } else { // 最小の値＋１がそのマスの最短の値となる
        D[i][j] = min(D[i - 1][j], D[i][j - 1]) + 1;
      }
    }
  }
  for (int i = H; i > 0; i--) {
    for (int j = W; j > 0; j--) {
      // 上のfor文で左上から＃の最短距離を数えたのに対し
      // ここのfor文では右下から＃の最短距離を数える（天才の発想）
      // 対極から二度数えることでそれぞれの撃墜ケースをなくす
      // また二度目のfor文では一度目のfor文との比較も行う。
      D[i][j] = min({D[i][j], D[i + 1][j] + 1, D[i][j + 1] + 1});
    }
  }
  for (int i = 1; i <= H; i++) {
    for (int j = 1; j <= W; j++) {
      ans = max(ans, D[i][j]);
    }
  }
  cout << ans << endl;
}

Fixed submission:
#include <bits/stdc++.h>
using namespace std;
#define INF 3000
#define INFF 9223372036854775807
#define ll long long
#define REP(i, n) for (int i = 0; i < n; i++)
#define REPP(i, m, n) for (int i = m; i < n; i++)
#define ALL(N) (N.begin(), N.end())
#define de cout << "debug" << endl;
#define push_back pb
template <class T> inline bool chmax(T &a, T b) {
  if (a < b) {
    a = b;
    return 1;
  }
  return 0;
}
template <class T> inline bool chmin(T &a, T b) {
  if (a > b) {
    a = b;
    return 1;
  }
  return 0;
}

int main() {
  cin.tie(0);
  ios::sync_with_stdio(false);
  int H, W;
  cin >> H >> W;
  char A[1010][1010];
  for (int i = 1; i <= H; i++) { // 後々のために1-indexにする
    for (int j = 1; j <= W; j++) {
      cin >> A[i][j];
    }
  }
  int D[1010][1010] = {};
  int ans = 0;
  for (int i = 0; i < 1002; i++) {
    // 盤外にINFを代入して、範囲外の参照に対処する
    D[0][i] = D[i][0] = D[H + 1][i] = D[i][W + 1] = INF;
  }
  for (int i = 1; i <= H; i++) {
    for (int j = 1; j <= W; j++) {
      if (A[i][j] == '#') { // #スタートだから０を代入
        D[i][j] = 0;
      } else { // 最小の値＋１がそのマスの最短の値となる
        D[i][j] = min(D[i - 1][j], D[i][j - 1]) + 1;
      }
    }
  }
  for (int i = H; i > 0; i--) {
    for (int j = W; j > 0; j--) {
      // 上のfor文で左上から＃の最短距離を数えたのに対し
      // ここのfor文では右下から＃の最短距離を数える（天才の発想）
      // 対極から二度数えることでそれぞれの撃墜ケースをなくす
      // また二度目のfor文では一度目のfor文との比較も行う。
      D[i][j] = min({D[i][j], D[i + 1][j] + 1, D[i][j + 1] + 1});
    }
  }
  for (int i = 1; i <= H; i++) {
    for (int j = 1; j <= W; j++) {
      ans = max(ans, D[i][j]);
    }
  }
  cout << ans << endl;
}