#include<cstdio>
#include<cstring>
#include<vector>
#include<queue>
#include<algorithm>
using namespace std;
#define all(x) begin(x), end(x)
#define sz(x) ((int)(x).size())
#define rep(i, a, b) for(int i = a; i < (b); ++i)
typedef long double db;
db ti = ((db)1e10) * ((db)1e10);
struct Point {
    db x, y;
    explicit Point(db x=0, db y=0): x(x), y(y) {}
    bool operator <(Point p) const {
        return tie(x, y) < tie(p.x, p.y);
    }
    bool operator ==(Point p) const {
        return tie(x, y) == tie(p.x, p.y);
    }
    Point operator -(Point p) const {
        return Point(x-p.x, y-p.y);
    }
    db cross(Point p) const {
        return x * p.y - y * p.x;
    }
    db cross(Point a, Point b) const {
        return (a-*this).cross(b-*this);
    }
};

vector<Point> convexHull(vector<Point> pts) {
    if (sz(pts) <= 1) {
        return pts;
    }
    sort(all(pts));
    vector<Point> h(sz(pts) + 1);
    int s=0, t=0;
    for (int it = 2; it--; s = --t, reverse(all(pts))) {
        for (Point p:pts) {
            while(t >= s + 2 && h[t-2].cross(h[t-1], p) <= 0) {
                t--;
            }
            h[t++] = p;
        }
    }
    return {h.begin(), h.begin() + t - (t == 2 && h[0] == h[1])};
}

int abs(int x) {
    return x>0?x:-x;
}
db dabs(db x) {
    return x > 0?x:-x;
}
int n;
int h[30][30];
const int R = 11;
int bound;
int a[20*(2*R+1)+5][20*(2*R+1)+5];
int d[20*(2*R+1)+5][20*(2*R+1)+5];
typedef pair<int, int> pii;
typedef pair<int, pii> tup;
priority_queue<tup, vector<tup>, greater<tup>> q;
int dx[] = {0, 1, 0, -1};
int dy[] = {1, 0, -1, 0};
vector<Point> all_points;
void start(int sx, int sy) {
    for (int i = 0; i <= bound; i++) {
        for (int j = 0; j <= bound; j++) {
            d[i][j] = 0x3f3f3f3f;
        }
    }
    d[R*n+sx][R*n+sy] = 0;
    q.push(tup(0, pii(R*n+sx, R*n+sy)));
    while(!q.empty()) {
        tup f = q.top();
        q.pop();
        int cx = f.second.first;
        int cy = f.second.second;
        int dist = f.first;
        if (dist > d[cx][cy]) {
            continue;
        }
        for (int i = 0; i < 4; i++) {
            int xx = cx+dx[i];
            int yy = cy+dy[i];
            int val = dist + abs(a[cx][cy] - a[xx][yy]) + 1;
            if (xx >= 0 && xx <= bound && yy >= 0 && yy <= bound && d[xx][yy] > val) {
                d[xx][yy] = val;
                q.push(tup(val, pii(xx, yy)));
            }
        }
    }
    for (int i = 0; i <= 2 * R; i++) {
        for (int j = 0; j <= 2 * R; j++){
            if (i != R || j != R) {
                int dist = d[i*n+sx][j*n+sy];
                Point pt((i - R) * n * ti / dist, (j - R) * n * ti / dist);
                all_points.push_back(pt);
            }
        }
    }
}

db Area(vector<Point> &v) {
    db a = v.back().cross(v[0]);
    rep(i, 0, sz(v) - 1) {
        a += v[i].cross(v[i+1]);
    }
    return dabs(a) / 2;
}

int main() {
    // freopen("g.in", "r", stdin);
    scanf("%d", &n);
    bound = (2 * R + 1) * n - 1;
    for (int i = 0; i < n; i++) {
        for (int j = 0; j < n; j++) {
            scanf("%d", &h[i][j]);
            for (int ri = 0; ri <= 2 * R; ri++) {
                for (int rj = 0; rj <= 2 * R; rj++) {
                    a[ri*n+i][rj*n+j] = h[i][j]; 
                }
            }
        }
    }
    for (int j = 0; j < n; j++) {
        start(0, j);
    }
    for (int i = 1; i < n; i++) {
        start(i, 0);
    }
    vector<Point> convex_hull = convexHull(all_points);
    // for (Point p: convex_hull) {
        // printf("%.5Lf %.5Lf\n", p.x, p.y);
    // }
    db area = Area(convex_hull);
    printf("%.20Lf\n", area);
    return 0;
}