#include using namespace std; #define x first #define y second #define ld long double #define mp make_pair const int N = 1e5 + 5; const ld eps = 1e-9; const ld inf = 1e18 + 1; int w, h; pair s, t; vector tab[N]; ld my_res; ld dist(pair a, pair b) { return sqrtl((a.first - b.first) * (a.first - b.first) + (a.second - b.second) * (a.second - b.second)); } bool equal_pair(pair a, pair b) { return abs(a.first - b.first) < eps && abs(a.second - b.second) < eps; } bool equal(ld a, ld b) { return abs(a - b) < eps; } ld next_moment(ld a, ld b, ld h) { return (b - a) / h; } int next_border(ld a, ld vec) { int less = (int) a; if (vec > 0) { if (equal(less + 1, a)) { return less + 2; } else { return less + 1; } } else { if (equal(less, a)) { return less - 1; } else { return less; } } } bool solve_one_dim() { if (s == t) { printf("0\n"); return true; } if (s.first == t.first) { int res = abs(s.second - t.second); int minw = min(s.second, t.second); int maxw = max(s.second, t.second); for (int i = minw; i < maxw; i++) { // cout << i << " " << abs(tab[s.first][i] - tab[s.first][i + 1]) << endl; res += abs(tab[s.first][i] - tab[s.first][i + 1]); } printf("%d\n", res); return true; } if (s.second == t.second) { // cout << "hejka " << endl; int res = abs(s.first - t.first); int minw = min(s.first, t.first); int maxw = max(s.first, t.first); for (int i = minw; i < maxw; i++) { res += abs(tab[i][s.second] - tab[i + 1][s.second]); } printf("%d\n", res); return true; } return false; } // bool solve_dim() { // } int direction(pair vec) { if (vec.first < 0 && vec.second > 0) { return 1; } if (vec.first < 0 && vec.second < 0) { return 2; } if (vec.first > 0 && vec.second < 0) { return 3; } if (vec.first > 0 && vec.second > 0) { return 4; } assert(false); } void handle(pair curr, pair vec, int &my_height) { if (equal_pair(curr, t)) { return; } pair closest = make_pair((int)curr.first, (int)curr.second); if (equal(closest.first + 1, curr.first)) { closest.first++; } if (equal(closest.second + 1, curr.second)) { closest.second++; } if (equal_pair(closest, curr)) { int max_block = 0; if (vec.first * vec.second > 0) { max_block = min(tab[closest.first][closest.second - 1], tab[closest.first - 1][closest.second]); } else { max_block = min(tab[closest.first][closest.second], tab[closest.first - 1][closest.second - 1]); } if (max_block > my_height) { // cout << "siema " << closest.first << " " << closest.second << " " << max_block << " " << my_height << endl; my_res += max_block - my_height; my_height = max_block; } if (direction(vec) == 1) { my_res += abs(my_height - tab[closest.first - 1][closest.second]); my_height = tab[closest.first - 1][closest.second]; // cout << "witam " << curr.first << " " << curr.second << " " << my_height << endl; } if (direction(vec) == 2) { int new_height = tab[closest.first - 1][closest.second - 1]; my_res += abs(my_height - new_height); my_height = new_height; } if (direction(vec) == 3) { int new_height = tab[closest.first][closest.second - 1]; my_res += abs(my_height - new_height); my_height = new_height; } if (direction(vec) == 4) { int new_height = tab[closest.first][closest.second]; my_res += abs(my_height - new_height); my_height = new_height; } } else if (equal(closest.first, curr.first)) { if (vec.first < 0) { int new_height = tab[closest.first - 1][closest.second]; my_res += abs(my_height - new_height); my_height = new_height; } else { int new_height = tab[closest.first][closest.second]; my_res += abs(my_height - new_height); my_height = new_height; } } else if (equal(closest.second, curr.second)) { if (vec.second > 0) { int new_height = tab[closest.first][closest.second]; my_res += abs(my_height - new_height); my_height = new_height; } else { int new_height = tab[closest.first][closest.second - 1]; my_res += abs(my_height - new_height); my_height = new_height; } } else { assert(false); } } int main() { scanf("%d%d%d%d%d%d", &w, &h, &s.y, &s.x, &t.y, &t.x); // assert(s.first % 2 == 1 && s.second % 2 == 1 && t.first % 2 == 1 && t.second % 2 == 1); my_res = dist(s, t); for (int i = 0; i < h / 2; i++) { tab[2 * i].resize(w); tab[2 * i + 1].resize(w); for (int j = 0; j < w / 2; j++) { int a; scanf("%d", &a); tab[2 * i][2 * j] = a; tab[2 * i][2 * j + 1] = a; tab[2 * i + 1][2 * j] = a; tab[2 * i + 1][2 * j + 1] = a; } } // for (int i = 0; i < h; i++) { // for (int j = 0; j < w; j++) { // printf("%d ", tab[i][j]); // } // printf("\n"); // } // printf("\n\n"); if (solve_one_dim()) { return 0; } pair curr = mp(s.first, s.second); pair endpoint = mp(t.first, t.second); pair vec = mp(endpoint.first - curr.first, endpoint.second - curr.second); int my_height; if (direction(vec) == 1) { my_height = tab[s.first - 1][s.second]; } if (direction(vec) == 2) { my_height = tab[s.first - 1][s.second - 1]; } if (direction(vec) == 3) { my_height = tab[s.first][s.second - 1]; } if (direction(vec) == 4) { my_height = tab[s.first][s.second]; } while (!equal_pair(curr, endpoint)) { ld next_event = next_moment(curr.first, endpoint.first, vec.first); next_event = min(next_event, next_moment(curr.first, next_border(curr.first, vec.first), vec.first)); next_event = min(next_event, next_moment(curr.second, next_border(curr.second, vec.second), vec.second)); curr.first += next_event * vec.first; curr.second += next_event * vec.second; handle(curr, vec, my_height); } cout << fixed << setprecision(10) << my_res << endl; }