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

#include <algorithm>
#include <assert.h>
#include <bitset>
#include <complex>
#include <deque>
#include <functional>
#include <iomanip>
#include <iostream>
#include <map>
#include <math.h>
#include <numeric>
#include <queue>
#include <set>
#include <stack>
#include <string>
#include <vector>
using namespace std;
typedef pair<int, int> P;
typedef long long ll;
typedef long double ld;
const int inf = 1e9 + 7;
const ll longinf = 1LL << 60;
#define REP(i, m, n) for (int i = (int)(m); i < (int)(n); ++i)
#define rep(i, n) REP(i, 0, n)
#define F first
#define S second

const int mx = 100010;
const ll mod = 1e9 + 7;

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

vector<vector<int>> da(500, vector<int>(500, 0));
int n;

int bfs(int s, int used[500][500]) {
  used[s / n][s % n] = 0;
  queue<P> q;
  q.push({s / n, s % n});
  int res = inf;
  while (!q.empty()) {
    auto p = q.front();
    q.pop();
    rep(i, 4) {
      int nx = p.F + dx[i];
      int ny = p.S + dy[i];
      if (nx < 0 || n <= nx || ny < 0 || n <= ny) {
        res = min(res, used[p.F][p.S]);
        if (res == 0) {
          return 0;
        }
        continue;
      }
      if (used[nx][ny] <= used[p.F][p.S] + (da[nx][ny] == 1 ? 1 : 0)) {
        continue;
      }
      used[nx][ny] = used[p.F][p.S] + (da[nx][ny] == 1 ? 1 : 0);
      q.push({nx, ny});
    }
  }
  return res;
}

int main() {
  cin >> n;
  vector<int> p(n * n);
  rep(i, n * n) {
    cin >> p[i];
    p[i]--;
  }
  ll ans = 0;

  vector<vector<int>> g(n, vector<int>(n, 1));
  vector<vector<int>> a(n, vector<int>(n));
  rep(i, n) rep(j, n) {
    a[i][j] = min(min(i, j), min(n - 1 - i, n - 1 - j)) + 1;
  }
  auto update = [&](int x, int y) {
    queue<P> q;
    q.push({x, y});
    while (!q.empty()) {
      auto p = q.front();
      q.pop();
      rep(i, 4) {
        int nx = p.F + dx[i];
        int ny = p.S + dy[i];
        if (nx < 0 || n <= nx || ny < 0 || n <= ny) {
          continue;
        }
        if (a[nx][ny] <= a[p.F][p.S] + g[p.F][p.S]) {
          continue;
        }
        a[nx][ny] = a[p.F][p.S] + g[p.F][p.S];
        q.push({nx, ny});
      }
    }
  };

  rep(i, n * n) {
    ans += a[p[i] / n][p[i] % n] - 1;
    g[p[i] / n][p[i] % n] = 0;
    update(p[i] / n, p[i] % n);
  }
  cout << ans << endl;
  return 0;
}

Error: TLE

Fixed submission:

#include <algorithm>
#include <assert.h>
#include <bitset>
#include <complex>
#include <deque>
#include <functional>
#include <iomanip>
#include <iostream>
#include <map>
#include <math.h>
#include <numeric>
#include <queue>
#include <set>
#include <stack>
#include <string>
#include <vector>
using namespace std;
typedef pair<int, int> P;
typedef long long ll;
typedef long double ld;
const int inf = 1e9 + 7;
const ll longinf = 1LL << 60;
#define REP(i, m, n) for (int i = (int)(m); i < (int)(n); ++i)
#define rep(i, n) REP(i, 0, n)
#define F first
#define S second

const int mx = 100010;
const ll mod = 1e9 + 7;

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

vector<vector<int>> da(500, vector<int>(500, 0));
int n;

int bfs(int s, int used[500][500]) {
  used[s / n][s % n] = 0;
  queue<P> q;
  q.push({s / n, s % n});
  int res = inf;
  while (!q.empty()) {
    auto p = q.front();
    q.pop();
    rep(i, 4) {
      int nx = p.F + dx[i];
      int ny = p.S + dy[i];
      if (nx < 0 || n <= nx || ny < 0 || n <= ny) {
        res = min(res, used[p.F][p.S]);
        if (res == 0) {
          return 0;
        }
        continue;
      }
      if (used[nx][ny] <= used[p.F][p.S] + (da[nx][ny] == 1 ? 1 : 0)) {
        continue;
      }
      used[nx][ny] = used[p.F][p.S] + (da[nx][ny] == 1 ? 1 : 0);
      q.push({nx, ny});
    }
  }
  return res;
}

int main() {
  cin >> n;
  vector<int> p(n * n);
  rep(i, n * n) {
    cin >> p[i];
    p[i]--;
  }
  ll ans = 0;
  rep(i, n * n) {
    int used[500][500];
    rep(i, 500) rep(j, 500) used[i][j] = inf;
    ans += bfs(p[n * n - 1 - i], used);
    da[p[n * n - 1 - i] / n][p[n * n - 1 - i] % n] = 1;
  }
  cout << ans << endl;
  return 0;
}