#include #include #include using namespace std; int main() { // Optimasi Fast I/O agar secepat kilat ios_base::sync_with_stdio(false); cin.tie(NULL); int H, W; if (!(cin >> H >> W)) return 0; vector grid(H); for (int i = 0; i < H; i++) { cin >> grid[i]; } int R = 2 * H - 1; int C = 2 * W - 1; int N = R * C; // Fungsi untuk mengecek apakah sebuah koordinat expanded adalah dinding (#) auto is_wall = [&](int r, int c) { if (r % 2 == 0 && c % 2 == 0) { return grid[r / 2][c / 2] == '#'; } return false; // Lorong sisipan selalu kosong }; // Array flat untuk jarak (16 juta elemen, sekitar 64MB memori, sangat aman) vector dist(N, -1); // Array Queue statis, ini jauh lebih cepat daripada std::queue vector q; q.reserve(N); int head = 0; q.push_back(0); dist[0] = 0; int target = N - 1; if (target == 0) { cout << 0 << "\n"; return 0; } while (head < q.size()) { int u = q[head++]; if (u == target) { cout << dist[u] << "\n"; return 0; } int r = u / C; int c = u % C; int d = dist[u]; int nd = d + 1; // 1. Bergerak ke sel bersebelahan (Masuk/keluar lorong) - Cost 1 if (c > 0) { int nr = r, nc = c - 1; if (!is_wall(nr, nc)) { int v = nr * C + nc; if (dist[v] == -1) { dist[v] = nd; q.push_back(v); } } } if (c < C - 1) { int nr = r, nc = c + 1; if (!is_wall(nr, nc)) { int v = nr * C + nc; if (dist[v] == -1) { dist[v] = nd; q.push_back(v); } } } if (r > 0) { int nr = r - 1, nc = c; if (!is_wall(nr, nc)) { int v = nr * C + nc; if (dist[v] == -1) { dist[v] = nd; q.push_back(v); } } } if (r < R - 1) { int nr = r + 1, nc = c; if (!is_wall(nr, nc)) { int v = nr * C + nc; if (dist[v] == -1) { dist[v] = nd; q.push_back(v); } } } // 2. Melompat melewati baris/kolom (Berjalan di lorong atau jalan normal) - Cost 1 if (c % 2 == 0) { // Lompat horizontal if (c >= 2) { int nr = r, nc = c - 2; if (!is_wall(nr, nc)) { int v = nr * C + nc; if (dist[v] == -1) { dist[v] = nd; q.push_back(v); } } } if (c < C - 2) { int nr = r, nc = c + 2; if (!is_wall(nr, nc)) { int v = nr * C + nc; if (dist[v] == -1) { dist[v] = nd; q.push_back(v); } } } } if (r % 2 == 0) { // Lompat vertikal if (r >= 2) { int nr = r - 2, nc = c; if (!is_wall(nr, nc)) { int v = nr * C + nc; if (dist[v] == -1) { dist[v] = nd; q.push_back(v); } } } if (r < R - 2) { int nr = r + 2, nc = c; if (!is_wall(nr, nc)) { int v = nr * C + nc; if (dist[v] == -1) { dist[v] = nd; q.push_back(v); } } } } } // Jika tidak ada jalan sama sekali cout << -1 << "\n"; return 0; }