/*#pragma GCC target ("avx2") #pragma GCC optimize ("O3") #pragma GCC optimize ("unroll-loops")*/ #include #define bit(n, i) (((n)>>(i))&1) #define cat(x) cout << #x << " = " << x << "\n" #define pb push_back #define mp make_pair #define se second #define fi first #define inf 2000000000 #define llinf 2000000000000000000LL #define forn(i, a, b) for(ll i = (a); i <= (b); ++i) #define all(x) (x).begin(), (x).end() #define ppc(x) __builtin_popcount(x) using namespace std; typedef long long ll; typedef double ld; typedef pair i2; typedef vector vi; typedef vector vll; /*const ll mod = 167772161; inline ll add(ll a, ll b) { a += b; if(a >= mod) a -= mod; return a; } inline ll sub(ll a, ll b) { return add(a, mod-b); } inline ll mul(ll a, ll b) { return a*b%mod; }*/ // segment intersection code taken from: // // https://cp-algorithms.com/geometry/segments-intersection.html // const double EPS = 1E-9; struct pt { double x, y; bool operator<(const pt& p) const { return x < p.x - EPS || (abs(x - p.x) < EPS && y < p.y - EPS); } }; struct line { double a, b, c; line() {} line(pt p, pt q) { a = p.y - q.y; b = q.x - p.x; c = -a * p.x - b * p.y; norm(); } void norm() { double z = sqrt(a * a + b * b); if (abs(z) > EPS) a /= z, b /= z, c /= z; } double dist(pt p) const { return a * p.x + b * p.y + c; } }; double det(double a, double b, double c, double d) { return a * d - b * c; } inline bool betw(double l, double r, double x) { return min(l, r) <= x + EPS && x <= max(l, r) + EPS; } inline bool intersect_1d(double a, double b, double c, double d) { if (a > b) swap(a, b); if (c > d) swap(c, d); return max(a, c) <= min(b, d) + EPS; } bool intersect(pt a, pt b, pt c, pt d, pt& left, pt& right) { if (!intersect_1d(a.x, b.x, c.x, d.x) || !intersect_1d(a.y, b.y, c.y, d.y)) return false; line m(a, b); line n(c, d); double zn = det(m.a, m.b, n.a, n.b); if (abs(zn) < EPS) { if (abs(m.dist(c)) > EPS || abs(n.dist(a)) > EPS) return false; if (b < a) swap(a, b); if (d < c) swap(c, d); left = max(a, c); right = min(b, d); return true; } else { left.x = right.x = -det(m.c, m.b, n.c, n.b) / zn; left.y = right.y = -det(m.a, m.c, n.a, n.c) / zn; return betw(a.x, b.x, left.x) && betw(a.y, b.y, left.y) && betw(c.x, d.x, left.x) && betw(c.y, d.y, left.y); } } ////////////////////////////////////////////////////////////////// bool myintersect(int ax1, int ay1, int ax2, int ay2, int bx1, int by1, int bx2, int by2) { pt x, y; pt a, b, c, d; a.x = ax1; a.y = ay1; b.x = ax2; b.y = ay2; c.x = bx1; c.y = by1; d.x = bx2; d.y = by2; return intersect(a, b, c, d, x, y); } bool goesthrough(int x1, int y1, int x2, int y2, int px, int py) { return myintersect(x1, y1, x2, y2, px, py, px+1, py) && myintersect(x1, y1, x2, y2, px, py, px-1, py) && myintersect(x1, y1, x2, y2, px, py, px, py+1) && myintersect(x1, y1, x2, y2, px, py, px, py-1); } vector T; int sx, sy, ex, ey; int main() { ios_base::sync_with_stdio(false); cin.tie(0); cout.tie(0); int w, h; cin >> w >> h >> sx >> sy >> ex >> ey; if(ex < sx) { swap(ex, sx); swap(ey, sy); } T.resize(w+1); forn(i, 0, w) T[i].resize(h); forn(j, 1, h/2) { forn(i, 1, w/2) { cin >> T[i][j]; } } double dx = ex-sx; double dy = ey-sy; double res = 0; forn(i, 1, w/2) { forn(j, 1, h/2) { int x1 = 2*i-2; int y1 = 2*j-2; int x2 = x1+2; int y2 = y1+2; bool goes11, goes12, goes21, goes22; goes11 = goes12 = goes21 = goes22 = false; // points if(goesthrough(sx, sy, ex, ey, x1, y1)) { goes11 = true; if(sy < y1) { res += abs(T[i][j]-T[i-1][j-1]); double mn = min(T[i-1][j], T[i][j-1]); double mx = max(T[i][j], T[i-1][j-1]); if(mn > mx) res += 2*(mn-mx); } } if(goesthrough(sx, sy, ex, ey, x2, y1)) { goes21 = true; if(sy > y1) { res += abs(T[i][j]-T[i+1][j-1]); double mn = min(T[i][j-1], T[i+1][j]); double mx = max(T[i][j], T[i+1][j-1]); if(mn > mx) res += 2*(mn-mx); } } if(goesthrough(sx, sy, ex, ey, x2, y2)) { goes22 = true; if(sy < y1) { res += abs(T[i][j]-T[i+1][j+1]); double mn = min(T[i][j+1], T[i+1][j]); double mx = max(T[i][j], T[i+1][j+1]); if(mn > mx) res += 2*(mn-mx); } } if(goesthrough(sx, sy, ex, ey, x1, y2)) { goes12 = true; if(sy > y1) { res += abs(T[i][j]-T[i-1][j+1]); double mn = min(T[i-1][j], T[i][j+1]); double mx = max(T[i][j], T[i-1][j+1]); if(mn > mx) res += 2*(mn-mx); } } // edges if(myintersect(sx, sy, ex, ey, x1, y1, x2, y1) && !goes11 && !goes21) { res += abs(T[i][j]-T[i][j-1]); } if(myintersect(sx, sy, ex, ey, x2, y1, x2, y2) && !goes21 && !goes22) { res += abs(T[i][j]-T[i+1][j]); } if(myintersect(sx, sy, ex, ey, x2, y2, x1, y2) && !goes22 && !goes12) { res += abs(T[i][j]-T[i][j+1]); } if(myintersect(sx, sy, ex, ey, x1, y2, x1, y1) && !goes12 && !goes11) { res += abs(T[i][j]-T[i-1][j]); } } } res /= 2; cout << setprecision(12) << fixed << res+sqrt(dx*dx+dy*dy); return 0; }