#include using namespace std; using ll=long long; using ld=double; #define FOR(i,a,b) for(ll i=a;i<(ll)b;++i) #define F(n) FOR(i,0,n) #define FF(n) FOR(j,0,n) #define aa first #define bb second #define PB push_back #define EPS 1e-6 #define EQ(a,b) (fabs(a-b)<=(fabs(a+b)*EPS)) #define MOD ((ll)(1e9+7)) //#define dbg while(0) cerr #define dbg cerr ll w, h, sx, sy, ex, ey; vector> m; void flipX() { sx = w - sx; ex = w - ex; F(h) { FF(w/2) { swap(m[i][j], m[i][w - j - 1]); } } } void flipY() { sy = h - sy; ey = h - ey; F(h/2) { FF(w) { swap(m[i][j], m[h - i - 1][j]); } } } int main(){ ios::sync_with_stdio(0);cin.tie(0); cin >> w >> h >> sx >> sy >> ex >> ey; m = vector>(h, vector(w)); for (int i = 0; i < h/2; i ++) { for (int j = 0; j < w/2; j ++) { cin >> m[2*i][2*j]; m[2*i+1][2*j] = m[2*i][2*j+1] = m[2*i+1][2*j+1] = m[2*i][2*j]; } } if (sx > ex) flipX(); if (sy > ey) flipY(); dbg << "start: " << sx << ", " << sy << endl; dbg << "end: " << ex << ", " << ey << endl; ld res = 0; vector> pts; // assume (sx, sy) is top left, (ex, ey) is bottom right for (int i = 0; i < ex - sx + 1; ++ i) { // find intersections with the y axis if (ex == sx) continue; pts.PB({sx + i, sy + i*(ey - sy) / ld(ex - sx)}); } for (int i = 0; i < ey - sy + 1; ++ i) { // intersections with the x axis if (ey == sy) continue; pts.PB({sx + i*(ex - sx) / ld(ey - sy), sy + i}); } sort(pts.begin(), pts.end()); int last = 0; ll lastHeight; for (int i = 1; i < pts.size(); ++ i) { if (EQ(pts[i].aa, pts[last].aa) && EQ(pts[i].bb, pts[last].bb)) { cerr << "CORNER" << endl; continue; } int ax = floor(pts[last].aa + EPS); int ay = floor(pts[last].bb + EPS); int bx = floor(pts[i].aa + EPS); int by = floor(pts[i].bb + EPS); lastHeight = m[ay][ax]; //dbg << pts[last].aa << ' ' << pts[last].bb << "; " << pts[i].aa << ' ' << pts[i].bb << endl; dbg << "(" << ax << ", " << ay << ") to (" << bx << ", " << by << "): " << ' '; dbg << m[ay][ax] << " to " << m[by][bx] << ". Res: " << res << endl; //dbg << m[ay][ax] << ", " << m[by][bx] << " " << abs(m[by][bx] - lastHeight) << endl; //dbg << res << endl; //dbg << endl; if (EQ(bx, pts[i].aa) && EQ(by, pts[i].bb) && m[by-1][bx] > lastHeight && m[by][bx-1] > lastHeight) { // Is an corner and must climb cerr << "CLIMBING CORNER" << endl; res += min(abs(lastHeight - m[by-1][bx]) + abs(m[by-1][bx] - m[by][bx]) , abs(lastHeight - m[by][bx-1]) + abs(m[by][bx-1] - m[by][bx])); } else { // Is a corner but doesn't have to climb res += abs(m[by][bx] - lastHeight); } last = i; } res += sqrt((ex - sx)*(ex - sx) + (ey - sy)*(ey - sy)); cout << fixed << setprecision(12) << res << endl; return 0; }