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

#include <bits/stdc++.h>
#define rep(i, n) for (int i = 0, i##_len = (n); i < i##_len; ++i)
#define reps(i, n) for (int i = 1, i##_len = (n); i <= i##_len; ++i)
#define rrep(i, n) for (int i = ((int)(n)-1); i >= 0; --i)
#define rreps(i, n) for (int i = ((int)(n)); i > 0; --i)
#define rep2(i, s, n) for (int i = (s); i < (int)(n); i++)
#define repc2(i, s, n) for (int i = (s); i <= (int)(n); i++)
#define inf 2e9
#define linf 9000000000000000000ll
#define all(v) v.begin(), v.end()
using namespace std;
typedef long long ll;

#define MAX_N 500
int n;
int p[MAX_N * MAX_N];
int dist[MAX_N][MAX_N];
bool isVacant[MAX_N][MAX_N];
const int dx[] = {-1, 0, 0, 1};
const int dy[] = {0, -1, 1, 0};
const int dx2[] = {-1, 1, -1, 1};
const int dy2[] = {-1, -1, 1, 1};

void update(int x, int y) {
  rep(i, 4) {
    int nx = x + dx[i], ny = y + dy[i];
    if (nx >= 0 && ny >= 0 && nx < n && ny < n) {
      if (isVacant[y][x] && dist[ny][nx] > dist[y][x]) {
        dist[ny][nx] = dist[y][x];
        update(nx, ny);
      }
      if (!isVacant[y][x] && dist[ny][nx] > dist[y][x] + 1) {
        dist[ny][nx] = dist[y][x] + 1;
        update(nx, ny);
      }
    }
  }
}

int main() {
  cin >> n;
  rep(i, n * n) {
    cin >> p[i];
    p[i]--;
  }
  rep(i, n * n) {
    int x = i % n;
    int y = i / n;
    dist[y][x] = min({x, y, n - 1 - x, n - 1 - y});
  }
  ll ans = 0;
  rep(i, n * n) {
    int x = p[i] % n;
    int y = p[i] / n;
    ans += dist[y][x];
    isVacant[y][x] = true;
    rep(i, 4) {
      int nx = x + dx[i], ny = y + dy[i];
      if (nx >= 0 && ny >= 0 && nx < n && ny < n) {
        if (dist[ny][nx] > dist[y][x]) {
          dist[ny][nx] = dist[y][x];
          update(nx, ny);
        }
      }
    }
  }
  cout << ans << endl;
  return 0;
}

Error: TLE

Fixed submission:

#include <bits/stdc++.h>
#define rep(i, n) for (int i = 0, i##_len = (n); i < i##_len; ++i)
#define reps(i, n) for (int i = 1, i##_len = (n); i <= i##_len; ++i)
#define rrep(i, n) for (int i = ((int)(n)-1); i >= 0; --i)
#define rreps(i, n) for (int i = ((int)(n)); i > 0; --i)
#define rep2(i, s, n) for (int i = (s); i < (int)(n); i++)
#define repc2(i, s, n) for (int i = (s); i <= (int)(n); i++)
#define inf 2e9
#define linf 9000000000000000000ll
#define all(v) v.begin(), v.end()
using namespace std;
typedef long long ll;

#define MAX_N 500
int n;
int p[MAX_N * MAX_N];
int dist[MAX_N][MAX_N];
bool isVacant[MAX_N][MAX_N];
const int dx[] = {-1, 0, 0, 1};
const int dy[] = {0, -1, 1, 0};
const int dx2[] = {-1, 1, -1, 1};
const int dy2[] = {-1, -1, 1, 1};

void update(int x, int y) {
  if (!(x >= 0 && y >= 0 && x < n && y < n))
    return;
  rep(i, 4) {
    int nx = x + dx[i], ny = y + dy[i];
    if (isVacant[y][x] && dist[ny][nx] > dist[y][x]) {
      dist[ny][nx] = dist[y][x];
      update(nx, ny);
    }
    if (!isVacant[y][x] && dist[ny][nx] > dist[y][x]) {
      dist[ny][nx] = dist[y][x] + 1;
      update(nx, ny);
    }
  }
}

int main() {
  cin >> n;
  rep(i, n * n) {
    cin >> p[i];
    p[i]--;
  }
  rep(i, n * n) {
    int x = i % n;
    int y = i / n;
    dist[y][x] = min({x, y, n - 1 - x, n - 1 - y});
  }
  ll ans = 0;
  rep(i, n * n) {
    int x = p[i] % n;
    int y = p[i] / n;
    ans += dist[y][x];
    isVacant[y][x] = true;
    rep(i, 4) {
      int nx = x + dx[i], ny = y + dy[i];
      if (dist[ny][nx] >= dist[y][x] + 1) {
        dist[ny][nx] = dist[y][x];
        update(nx, ny);
      }
    }
    rep(i, 4) {
      int nx = x + dx2[i], ny = y + dy2[i];
      if (dist[ny][nx] >= dist[y][x] + 2) {
        dist[ny][nx] = dist[y][x] + 1;
        update(nx, ny);
      }
    }
  }
  cout << ans << endl;
  return 0;
}