Problem p02670 (C++) — buggy submission, verdict: Runtime Error

#include <algorithm>
#include <bitset>
#include <cmath>
#include <iomanip>
#include <iostream>
#include <map>
#include <queue>
#include <set>
#include <stack>
#include <string>
#include <vector>
using namespace std;
typedef long long ll;
typedef pair<ll, ll> P;
typedef pair<ll, P> P1;
typedef pair<P, P> P2;
#define pu push
#define pb push_back
#define mp make_pair
#define eps 1e-7
#define INF 1000000000
#define fi first
#define sc second
#define rep(i, x) for (ll i = 0; i < x; i++)
#define repn(i, x) for (ll i = 1; i <= x; i++)
#define SORT(x) sort(x.begin(), x.end())
#define ERASE(x) x.erase(unique(x.begin(), x.end()), x.end())
#define POSL(x, v) (lower_bound(x.begin(), x.end(), v) - x.begin())
#define POSU(x, v) (upper_bound(x.begin(), x.end(), v) - x.begin())

const int MAX = 510;
const int MOD = 1000000007;

// 四方向への移動ベクトル
const int dx[4] = {1, 0, -1, 0};
const int dy[4] = {0, 1, 0, -1};

ll d[MAX][MAX];
bool maze[MAX][MAX];

void dfs(ll x, ll y) {
  ll z = d[x][y] + maze[x][y];
  // 距離が減るところをdfsで減らす
  rep(i, 4) {
    ll nx = x + dx[i];
    ll ny = y + dy[i];
    if (nx < 0 or ny < 0)
      continue;
    if (d[nx][ny] > z) {
      d[nx][ny] = z;
      dfs(nx, ny);
    }
  }
}

int main() {
  ll N;
  cin >> N;
  ll ans = 0;
  // 外周までの距離の初期設定
  rep(i, N) rep(j, N) d[i][j] = min(min(i, j), min(N - i - 1, N - j - 1));
  // pの入力
  vector<ll> p(N * N);
  rep(i, N * N) cin >> p[i];
  rep(i, N * N) p[i]--;
  // 表示用
  // rep(i,N){ rep(j,N) { cout << d[i][j] << " "; } cout << endl; }
  // mazeの初期化、最初は全部通れない
  rep(i, MAX) rep(j, MAX) maze[i][j] = true;
  // dfsの操作
  rep(i, N * N) {
    ll x = p[i] / N;
    ll y = p[i] % N;
    ans += d[x][y];
    // cout << i << " " << x << " " << y << " " << ans << endl;
    maze[x][y] = false;
    dfs(x, y);
  }
  cout << ans << endl;
}


Error: -11

Fixed submission:

#include <algorithm>
#include <bitset>
#include <cmath>
#include <iomanip>
#include <iostream>
#include <map>
#include <queue>
#include <set>
#include <stack>
#include <string>
#include <vector>
using namespace std;
typedef long long ll;
typedef pair<ll, ll> P;
typedef pair<ll, P> P1;
typedef pair<P, P> P2;
#define pu push
#define pb push_back
#define mp make_pair
#define eps 1e-7
#define INF 1000000000
#define fi first
#define sc second
#define rep(i, x) for (ll i = 0; i < x; i++)
#define repn(i, x) for (ll i = 1; i <= x; i++)
#define SORT(x) sort(x.begin(), x.end())
#define ERASE(x) x.erase(unique(x.begin(), x.end()), x.end())
#define POSL(x, v) (lower_bound(x.begin(), x.end(), v) - x.begin())
#define POSU(x, v) (upper_bound(x.begin(), x.end(), v) - x.begin())

const int MAX = 510;
const int MOD = 1000000007;

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

  vector<vector<ll>> up(N + 2, vector<ll>(N + 2));
  vector<vector<ll>> down(N + 2, vector<ll>(N + 2));
  vector<vector<ll>> left(N + 2, vector<ll>(N + 2));
  vector<vector<ll>> right(N + 2, vector<ll>(N + 2));
  // それぞれのマスについて　、それぞれの方向での最小回数を保存する
  rep(i, N) {
    rep(j, N) {
      up[i][j] = i;
      down[i][j] = N - i - 1;
      left[i][j] = j;
      right[i][j] = N - j - 1;
    }
  }

  rep(i, N * N) {
    ll tate = a[i] / N;
    ll yoko = a[i] % N;
    // a[i] は tate yoko　の座標に存在している
    // ans += min( min(up[tate][yoko] , down[tate][yoko] ) , min(
    // left[tate][yoko] , right[tate][yoko] )  );
    // 常に一回曲がるところまで追っていく
    ll tmp = INF;
    ll tmpu = INF, tmpd = INF;
    ll tmpl = INF, tmpr = INF;

    tmp = min(min(up[tate][yoko], down[tate][yoko]),
              min(left[tate][yoko], right[tate][yoko]));
    rep(j, N) {
      // はじめ上下に移動する場合、　i , yoko で折り返す
      if (j < tate) {
        tmpu = min(up[tate][yoko] - up[j][yoko] + left[j][yoko],
                   up[tate][yoko] - up[j][yoko] + right[j][yoko]);

      } else {
        tmpd = min(down[tate][yoko] - down[j][yoko] + left[j][yoko],
                   down[tate][yoko] - down[j][yoko] + right[j][yoko]);
      }
    }
    rep(j, N) {
      // はじめ左右に移動する場合、　tate , j で折り返す
      if (j < yoko) {
        tmpl = min(left[tate][yoko] - left[j][yoko] + up[j][yoko],
                   left[tate][yoko] - left[j][yoko] + down[j][yoko]);
      } else {
        tmpd = min(right[tate][yoko] - right[j][yoko] + up[j][yoko],
                   right[tate][yoko] - right[j][yoko] + down[i][yoko]);
      }
    }

    cout << i << " " << tmpu << " " << tmpd << " " << tmpl << " " << tmpr
         << endl;
    tmp = min(min(tmpu, tmpd), min(tmpl, tmpr));
    // cout << i << " " << tmp << endl;
    ans += tmp;

    rep(j, N) {
      // yoko のleft rightの減少
      if (j < yoko) {
        right[tate][j]--;
        if (right[tate][j] < 0)
          right[tate][j] = 0;
      } else {
        left[tate][j]--;
        if (left[tate][j] < 0)
          left[tate][j] = 0;
      }
    }

    rep(j, N) {
      // tate の up down の減少
      if (j < tate) {
        down[j][yoko]--;
        if (down[j][yoko] < 0)
          down[j][yoko] = 0;
      } else {
        up[j][yoko]--;
        if (up[j][yoko] < 0)
          up[j][yoko] = 0;
      }
    }
  }

  cout << ans << endl;
}