#define _USE_MATH_DEFINES #include #ifdef LOC #include "debuglib.h" #else #define deb(...) #define DBP(...) #endif using namespace std; using ll = long long; using Vi = vector; using Pii = pair; #define pb push_back #define mp make_pair #define x first #define y second #define rep(i, b, e) for (int i = (b); i < (e); i++) #define each(a, x) for (auto& a : (x)) #define all(x) (x).begin(), (x).end() #define sz(x) int((x).size()) int uplg(int n) { return 32-__builtin_clz(n); } int uplg(ll n) { return 64-__builtin_clzll(n); } using dbl = double; int cmp(dbl a, dbl b, dbl eps=1e-9) { return (a > b+eps) - (a+eps < b); } template struct bvec2 { T x, y; S operator+(S r) const {return{x+r.x,y+r.y};} S operator-(S r) const {return{x-r.x,y-r.y};} S operator*(T r) const { return {x*r, y*r}; } S operator/(T r) const { return {x/r, y/r}; } T dot(S r) const { return x*r.x + y*r.y; } T cross(S r) const { return x*r.y - y*r.x; } T len2() const { return x*x + y*y; } double len() const { return hypot(x, y); } S perp() const { return {-y,x}; } // CCW pair yx() const { return {y, x}; } double angle() const { //[0;2*PI] CCW from OX double a = atan2(y, x); return (a < 0 ? a+2*M_PI : a); } }; struct vec2d : bvec2 { vec2d() : bvec2{0, 0} {} vec2d(double a, double b) : bvec2{a, b} {} bool upper() const { return (cmp(y, 0) ?: cmp(x, 0)) >= 0; } int angleCmp(vec2d r) const { return r.upper() - upper() ?: cmp(0, cross(r)); } // Compare by angle, length if angles equal bool operator<(vec2d r) const { return (angleCmp(r) ?: cmp(len2(), r.len2())) < 0; } bool operator==(vec2d r) const { return !cmp(x, r.x) && !cmp(y, r.y); } vec2d unit() const { return *this / len(); } vec2d rotate(double a) const { // CCW return {x*cos(a) - y*sin(a), x*sin(a) + y*cos(a)}; } }; using vec2 = vec2d; template struct bline2 { P v; // Normal vector [A; B] T c; // Offset (C parameter of equation) DBP(v, c); static S through(P a, P b) { return { (a-b).perp(), a.cross(b) }; } static S parallel(P a, S b) { return { b.v, b.v.dot(a) }; } static S perp(P a, S b) { return { b.v.perp(), b.v.cross(a) }; } double distTo(P a) { return fabs(v.dot(a)-c) / v.len(); } }; struct line2d : bline2 { line2d() : bline2{{}, 0} {} line2d(vec2d a, double b) : bline2{a, b} {} int side(vec2d a) { return cmp(v.dot(a),c); } bool intersect(line2d a, vec2d& out) { double d = v.cross(a.v); if (!cmp(d, 0)) return 0; out = (v*a.c - a.v*c).perp() / d; return 1; } }; using line2 = line2d; bool isKek(vec2 p) { return p == vec2(dbl(llround(p.x)), dbl(llround(p.y))); } dbl solve1d(Vi& vec) { deb(vec); dbl ans = sz(vec)*2 - 2; rep(i, 1, sz(vec)) ans += abs(vec[i]-vec[i-1]); return ans; } dbl solve2d(vector& G) { int n = sz(G), m = sz(G[0]); dbl ans = sqrt((n-1)*(n-1) + (m-1)*(m-1)) * 2; line2 path = line2::through({0.5, 0.5}, {n-0.5, m-0.5}); rep(i, 1, m) { line2 line = line2::through({0, dbl(i)}, {1, dbl(i)}); vec2 p; assert(path.intersect(line, p)); if (isKek(p)) continue; int j = int(p.x); ans += abs(G[j][i-1] - G[j][i]); } rep(i, 1, n) { line2 line = line2::through({dbl(i), 0}, {dbl(i), 1}); vec2 p; assert(path.intersect(line, p)); if (isKek(p)) continue; int j = int(p.y); ans += abs(G[i-1][j] - G[i][j]); } rep(i, 1, n) rep(j, 1, m) { if (!path.side({dbl(i), dbl(j)})) { int mx = max(max(G[i-1][j-1], G[i][j]), max(G[i-1][j], G[i][j-1])); ans += mx - G[i-1][j-1]; ans += mx - G[i][j]; } } return ans; } int main() { cin.sync_with_stdio(0); cin.tie(0); cout << fixed << setprecision(12); int w, h, sx, sy, ex, ey; cin >> w >> h >> sx >> sy >> ex >> ey; w /= 2; h /= 2; sx /= 2; sy /= 2; ex /= 2; ey /= 2; vector grid(w, Vi(h)); rep(y, 0, h) rep(x, 0, w) cin >> grid[x][y]; int minX = min(sx, ex), minY = min(sy, ey); int maxX = max(sx, ex), maxY = max(sy, ey); vector grid2(maxX-minX+1, Vi(maxY-minY+1)); for (int i = minX; i <= maxX; i++) { for (int j = minY; j <= maxY; j++) { grid2[i-minX][j-minY] = grid[i][j]; } } if (sx > ex) { reverse(all(grid2)); swap(sx, ex); } if (sy > ey) { each(r, grid2) reverse(all(r)); swap(sy, ey); } dbl ans = 0; if (sx == ex && sy == ey) { ans = 0; } else if (sx == ex) { assert(sz(grid2) == 1); ans = solve1d(grid2[0]); } else if (sy == ey) { Vi tmp(sz(grid2)); rep(i, 0, sz(tmp)) tmp[i] = grid2[i][0]; ans = solve1d(tmp); } else { ans = solve2d(grid2); } cout << ans << '\n'; return 0; }