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

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

typedef long long ll;
typedef unsigned long long ull;
typedef pair<ll, ll> P;

#define fi first
#define se second
#define repl(i, a, b) for (ll i = (ll)(a); i < (ll)(b); i++)
#define rep(i, n) repl(i, 0, n)
#define all(x) (x).begin(), (x).end()
#define dbg(x) cout << #x "=" << x << endl
#define mmax(x, y) (x > y ? x : y)
#define mmin(x, y) (x < y ? x : y)
#define maxch(x, y) x = mmax(x, y)
#define minch(x, y) x = mmin(x, y)
#define uni(x) x.erase(unique(all(x)), x.end())
#define exist(x, y) (find(all(x), y) != x.end())
#define bcnt __builtin_popcountll

#define INF INT_MAX / 3
#define mod 1000000007

struct state {
  int i, j, d;
};
int di[] = {-1, 0, +1, 0};
int dj[] = {0, -1, 0, +1};

bool used[505][505];
bool vis[505][505][505];
int dist[505][505];

int main() {

  int N;
  cin >> N;
  vector<int> A(N * N);
  rep(i, N * N) {
    scanf("%d", &A[i]);
    A[i]--;
  }

  rep(i, N) rep(j, N) {
    vis[i][j][min({i, j, N - 1 - i, N - 1 - j}) + 1] = true;
    used[i][j] = true;
    dist[i][j] = min({i, j, N - 1 - i, N - 1 - j}) + 1;
  }

  int res = 0;
  rep(k, A.size()) {
    int ni = A[k] / N, nj = A[k] % N;
    int ans = dist[ni][nj];
    ans--;
    res += ans;
    used[ni][nj] = false;

    queue<state> que;
    que.push((state){ni, nj, ans});
    vis[ni][nj][ans] = true;
    while (que.size()) {
      state s = que.front();
      que.pop();
      if (s.d > dist[s.i][s.j])
        continue;
      rep(dir, 4) {
        int ci = s.i + di[dir], cj = s.j + dj[dir];
        if (ci < 0 || ci >= N || cj < 0 || cj >= N)
          continue;
        int cost = (used[ci][cj] ? 1 : 0);
        if (s.d + cost <= N && !vis[ci][cj][s.d + cost]) {
          if (s.d + cost >= dist[ci][cj])
            continue;
          que.push((state){ci, cj, s.d + cost});
          vis[ci][cj][s.d + cost] = true;
          minch(dist[ci][cj], s.d + cost);
        }
      }
    }
  }
  cout << res << endl;

  return 0;
}


Error: TLE

Fixed submission:

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

typedef long long ll;
typedef unsigned long long ull;
typedef pair<ll, ll> P;

#define fi first
#define se second
#define repl(i, a, b) for (ll i = (ll)(a); i < (ll)(b); i++)
#define rep(i, n) repl(i, 0, n)
#define all(x) (x).begin(), (x).end()
#define dbg(x) cout << #x "=" << x << endl
#define mmax(x, y) (x > y ? x : y)
#define mmin(x, y) (x < y ? x : y)
#define maxch(x, y) x = mmax(x, y)
#define minch(x, y) x = mmin(x, y)
#define uni(x) x.erase(unique(all(x)), x.end())
#define exist(x, y) (find(all(x), y) != x.end())
#define bcnt __builtin_popcountll

#define INF INT_MAX / 3
#define mod 1000000007

struct state {
  int i, j, d;
};
int di[] = {-1, 0, +1, 0};
int dj[] = {0, -1, 0, +1};

bool used[505][505];
bool vis[505][505][505];
int dist[505][505];

int main() {
  cin.tie(0);
  ios::sync_with_stdio(false);

  int N;
  cin >> N;
  vector<int> A(N * N);
  rep(i, N * N) {
    cin >> A[i];
    A[i]--;
  }

  rep(i, N) rep(j, N) {
    vis[i][j][min({i, j, N - 1 - i, N - 1 - j}) + 1] = true;
    used[i][j] = true;
    dist[i][j] = min({i, j, N - 1 - i, N - 1 - j}) + 1;
  }

  ll res = 0;
  rep(k, A.size()) {
    int ni = A[k] / N, nj = A[k] % N;
    int ans = dist[ni][nj];
    ans--;
    res += (ll)ans;
    used[ni][nj] = false;

    queue<state> que;
    que.push((state){ni, nj, ans});
    vis[ni][nj][ans] = true;
    while (que.size()) {
      state s = que.front();
      que.pop();
      rep(dir, 4) {
        int ci = s.i + di[dir], cj = s.j + dj[dir];
        if (ci < 0 || ci >= N || cj < 0 || cj >= N)
          continue;
        int cost = (used[ci][cj] ? 1 : 0);
        if (s.d + cost < N && !vis[ci][cj][s.d + cost]) {
          if (s.d + cost > dist[ci][cj])
            continue;
          que.push((state){ci, cj, s.d + cost});
          vis[ci][cj][s.d + cost] = true;
          minch(dist[ci][cj], s.d + cost);
        }
      }
    }
  }
  cout << res << endl;

  return 0;
}