HackerRank Find the Path problem solution YASH PAL, 31 July 2024 In this HackerRank Find the Path problem solution You must answer q queries. In each query, you are given the coordinates of two cells, (r1,c1) and (r2, c2). You must find and print the minimum possible weight of a path connecting them. Problem solution in Java. import java.io.ByteArrayInputStream; import java.io.IOException; import java.io.InputStream; import java.io.PrintWriter; import java.util.Arrays; import java.util.InputMismatchException; public class C { InputStream is; PrintWriter out; String INPUT = ""; void solve() { int n = ni(), m = ni(); int[][] a = new int[m][n]; for(int i = 0;i < n;i++){ for(int j = 0;j < m;j++){ a[j][i] = ni(); } } d = new long[m][n][][]; build(0, m, a); int Q = ni(); for(int q = 0;q < Q;q++){ int sc = ni(), sr = ni(); int tc = ni(), tr = ni(); if(sr > tr){ {int du = tr; tr = sr; sr = du;} {int du = tc; tc = sc; sc = du;} } out.println(go(0, m, sr, sc, tr, tc, a)); } } static long go(int L, int R, int sr, int sc, int tr, int tc, int[][] a) { int M = L+R>>>1; int m = a[0].length; long ret = Long.MAX_VALUE; for(int i = 0;i < m;i++){ ret = Math.min(ret, d[M][i][sr-L][sc] + d[M][i][tr-L][tc] - a[M][i]); } if(sr <= M && M <= tr){ return ret; } if(R-L <= 1)return ret; if(tr < M){ return Math.min(ret, go(L, M, sr, sc, tr, tc, a)); }else{ return Math.min(ret, go(M, R, sr, sc, tr, tc, a)); } } static long[][][][] d; static void build(int L, int R, int[][] a) { int m = a[0].length; int M = L+R>>>1; if(d[M][0] != null)return; for(int i = 0;i < m;i++){ d[M][i] = dijk(a, M, i, L, R); } if(R-L <= 1)return; build(L, M, a); build(M, R, a); } public static long[][] dijk(int[][] a, int sr, int sc, int L, int R) { int m = a[0].length; long[][] td = new long[R-L][m]; for(int i = 0;i < R-L;i++){ Arrays.fill(td[i], Long.MAX_VALUE / 3); } td[sr-L][sc] = 0; MinHeapL q = new MinHeapL((R-L)*m); q.add((sr-L)*m+sc, 0L); td[sr-L][sc] = a[sr][sc]; int[] dr = { 1, 0, -1, 0 }; int[] dc = { 0, 1, 0, -1 }; while(q.size() > 0){ int cur = q.argmin(); q.remove(cur); int r = cur / m, c = cur % m; for(int k = 0;k < 4;k++){ int nr = r + dr[k], nc = c + dc[k]; if(nr >= L-L && nr < R-L && nc >= 0 && nc < m){ long nd = td[r][c] + a[nr+L][nc]; if(nd < td[nr][nc]){ td[nr][nc] = nd; q.update(nr*m+nc, nd); } } } } return td; } public static class MinHeapL { public long[] a; public int[] map; public int[] imap; public int n; public int pos; public static long INF = Long.MAX_VALUE; public MinHeapL(int m) { n = Integer.highestOneBit((m+1)<<1); a = new long[n]; map = new int[n]; imap = new int[n]; Arrays.fill(a, INF); Arrays.fill(map, -1); Arrays.fill(imap, -1); pos = 1; } public long add(int ind, long x) { int ret = imap[ind]; if(imap[ind] < 0){ a[pos] = x; map[pos] = ind; imap[ind] = pos; pos++; up(pos-1); } return ret != -1 ? a[ret] : x; } public long update(int ind, long x) { int ret = imap[ind]; if(imap[ind] < 0){ a[pos] = x; map[pos] = ind; imap[ind] = pos; pos++; up(pos-1); }else{ a[ret] = x; up(ret); down(ret); } return x; } public long remove(int ind) { if(pos == 1)return INF; if(imap[ind] == -1)return INF; pos--; int rem = imap[ind]; long ret = a[rem]; map[rem] = map[pos]; imap[map[pos]] = rem; imap[ind] = -1; a[rem] = a[pos]; a[pos] = INF; map[pos] = -1; up(rem); down(rem); return ret; } public long min() { return a[1]; } public int argmin() { return map[1]; } public int size() { return pos-1; } private void up(int cur) { for(int c = cur, p = c>>>1;p >= 1 && a[p] > a[c];c>>>=1, p>>>=1){ long d = a[p]; a[p] = a[c]; a[c] = d; int e = imap[map[p]]; imap[map[p]] = imap[map[c]]; imap[map[c]] = e; e = map[p]; map[p] = map[c]; map[c] = e; } } private void down(int cur) { for(int c = cur;2*c < pos;){ int b = a[2*c] < a[2*c+1] ? 2*c : 2*c+1; if(a[b] < a[c]){ long d = a[c]; a[c] = a[b]; a[b] = d; int e = imap[map[c]]; imap[map[c]] = imap[map[b]]; imap[map[b]] = e; e = map[c]; map[c] = map[b]; map[b] = e; c = b; }else{ break; } } } } void run() throws Exception { is = INPUT.isEmpty() ? System.in : new ByteArrayInputStream(INPUT.getBytes()); out = new PrintWriter(System.out); long s = System.currentTimeMillis(); solve(); out.flush(); if(!INPUT.isEmpty())tr(System.currentTimeMillis()-s+"ms"); } public static void main(String[] args) throws Exception { new C().run(); } private byte[] inbuf = new byte[1024]; private int lenbuf = 0, ptrbuf = 0; private int readByte() { if(lenbuf == -1)throw new InputMismatchException(); if(ptrbuf >= lenbuf){ ptrbuf = 0; try { lenbuf = is.read(inbuf); } catch (IOException e) { throw new InputMismatchException(); } if(lenbuf <= 0)return -1; } return inbuf[ptrbuf++]; } private boolean isSpaceChar(int c) { return !(c >= 33 && c <= 126); } private int skip() { int b; while((b = readByte()) != -1 && isSpaceChar(b)); return b; } private double nd() { return Double.parseDouble(ns()); } private char nc() { return (char)skip(); } private String ns() { int b = skip(); StringBuilder sb = new StringBuilder(); while(!(isSpaceChar(b))){ // when nextLine, (isSpaceChar(b) && b != ' ') sb.appendCodePoint(b); b = readByte(); } return sb.toString(); } private char[] ns(int n) { char[] buf = new char[n]; int b = skip(), p = 0; while(p < n && !(isSpaceChar(b))){ buf[p++] = (char)b; b = readByte(); } return n == p ? buf : Arrays.copyOf(buf, p); } private char[][] nm(int n, int m) { char[][] map = new char[n][]; for(int i = 0;i < n;i++)map[i] = ns(m); return map; } private int[] na(int n) { int[] a = new int[n]; for(int i = 0;i < n;i++)a[i] = ni(); return a; } private int ni() { int num = 0, b; boolean minus = false; while((b = readByte()) != -1 && !((b >= '0' && b <= '9') || b == '-')); if(b == '-'){ minus = true; b = readByte(); } while(true){ if(b >= '0' && b <= '9'){ num = num * 10 + (b - '0'); }else{ return minus ? -num : num; } b = readByte(); } } private long nl() { long num = 0; int b; boolean minus = false; while((b = readByte()) != -1 && !((b >= '0' && b <= '9') || b == '-')); if(b == '-'){ minus = true; b = readByte(); } while(true){ if(b >= '0' && b <= '9'){ num = num * 10 + (b - '0'); }else{ return minus ? -num : num; } b = readByte(); } } private static void tr(Object... o) { System.out.println(Arrays.deepToString(o)); } } {“mode”:”full”,”isActive”:false} Problem solution in C++. #include <bits/stdc++.h> using namespace std; int N, M; vector<vector<int64_t>> G; const int64_t INF = 1e11; vector<vector<int64_t>> dijk(int r, int c, int L, int R) { set<pair<int64_t, pair<int, int>>> Q; vector<vector<int64_t>> D(N, vector<int64_t>(R-L+1, INF)); Q.insert(make_pair(0, make_pair(r,c))); vector<vector<int>> dirs = {{1,0},{0,1},{-1,0},{0,-1}}; while (!Q.empty()) { auto curr = *Q.begin(); Q.erase(Q.begin()); int64_t d = curr.first; int r = curr.second.first, c = curr.second.second; if (d > D[r][c-L]) { continue; } D[r][c-L] = d; for (auto dir : dirs) { int cr = r+dir[0]; int cc = c+dir[1]; if (cr < 0 || cc < L || cr >= N || cc > R) continue; int64_t cd = d + G[cr][cc]; if (cd < D[cr][cc-L]) { Q.insert(make_pair(cd, make_pair(cr, cc))); D[cr][cc-L] = cd; } } } return D; } vector<vector<int>> Qs; vector<int64_t> ans; vector<unordered_map<int, pair<int, vector<vector<int64_t>>>>> SPs(7); void div_and_conq(int l, int r, vector<int> Qis) { if (l > r) return; int mid = (r+l)/2; for (int i = 0; i < N; ++i) { SPs[i][mid] = make_pair(l, dijk(i, mid, l, r)); } vector<int> Qls, Qrs; for (int i : Qis) { if (Qs[i][1] < mid && Qs[i][3] < mid) { Qls.push_back(i); } else if (Qs[i][1] > mid && Qs[i][3] > mid) { Qrs.push_back(i); } else { for (int j = 0; j < N; ++j) { for (auto& kv : SPs[j]) { int mid = kv.first; int upperl = kv.second.first; auto& SP = kv.second.second; int64_t d = SP[Qs[i][0]][Qs[i][1]-upperl]+SP[Qs[i][2]][Qs[i][3]-upperl]+G[j][mid]; ans[i] = min(ans[i], d); } } } } div_and_conq(l, mid-1, Qls); div_and_conq(mid+1, r, Qrs); for (int i = 0; i < N; ++i) { SPs[i].erase(mid); } } int main() { ios::sync_with_stdio(false); cin >> N >> M; G.assign(N, vector<int64_t>(M)); for (auto &v : G) { for (int64_t& i : v) { cin >> i; } } int Q; cin >> Q; Qs.resize(Q); ans.assign(Q, INF); vector<int> Qis; for (int i = 0; i < Q; ++i) { int a,b,c,d; cin >> a >> b >> c >> d; Qs[i] = {a,b,c,d}; Qis.push_back(i); } div_and_conq(0, M-1, Qis); for (int64_t i : ans) { cout << i << endl; } return 0; } {“mode”:”full”,”isActive”:false} Problem solution in C. #include <assert.h> #include <limits.h> #include <stddef.h> #include <stdint.h> #include <stdio.h> #include <stdlib.h> #include <string.h> #define MIN(a,b) (((a)<(b))?(a):(b)) #define MAX(a,b) (((a)>(b))?(a):(b)) #define MAX_N 7 #define MAX_M 5000 #define LOG2_MAX_M 13 #define MAX_Q 30000 #define INFINITY INT_MAX #define N(r, c) ((r) * (m) + (c)) #define ROW(n) ((n) / (m)) #define COL(n) ((n) % (m)) #define HEAP_KEY(pri, n) (((uint64_t)pri << 32) | n) #define HEAP_PRI(key) ((int)(key >> 32)) #define HEAP_N(key) ((int)key) #define PARENT(i) (((i) - 1) / 2) #define LEFT(i) (2 * (i) + 1) #define RIGHT(i) (2 * (i) + 2) typedef uint64_t heap_type; struct node { int depth; int left, mid, right; struct node *child[2]; }; struct node *root; static int n; static int m; static int q; static int visited[MAX_N * MAX_M]; static int length[MAX_N * MAX_M]; static int dist[LOG2_MAX_M][MAX_N][MAX_N * MAX_M]; static heap_type queue[MAX_N * MAX_M * 4]; static int num_queue; static inline void swap_node(heap_type *a, int x, int y) { heap_type tmp = a[x]; a[x] = a[y]; a[y] = tmp; } static void sift_down(heap_type *a, int i, int size) { while (1) { int l = LEFT(i); int r = RIGHT(i); int min; if (r >= size) { if (l >= size) { break; } min = l; } else { if (a[r] >= a[l]) { min = l; } else { min = r; } } if (a[min] >= a[i]) { break; } swap_node(a, i, min); i = min; } } static void sift_up(heap_type *a, int i, int size) { while (i) { int p = PARENT(i); if (a[p] <= a[i]) { break; } swap_node(a, p, i); i = p; } } static void pop_heap(heap_type *a, int size) { swap_node(a, 0, size-1); sift_down(a, 0, size-1); } static void push_heap(heap_type *a, int size) { sift_up(a, size-1, size); } static void dijkstra(struct node *s, int i, int begin) { int *mind = dist[s->depth][i]; for (int r = 0; r < n; r++) { for (int c = s->left; c <= s->right; c++) { visited[N(r,c)] = 0; mind[N(r,c)] = INFINITY; } } num_queue = 0; mind[begin] = length[begin]; queue[num_queue++] = HEAP_KEY(mind[begin], begin); push_heap(queue, num_queue); while (num_queue) { pop_heap(queue, num_queue); int u = queue[--num_queue]; visited[u] = 1; static const int offsets[] = { 0, -1, 0, 1, -1, 0, 1, 0 }; for (int j = 0; j < 4; j++) { int vr = ROW(u) + offsets[j]; int vc = COL(u) + offsets[4+j]; if (vr < 0 || vr >= n || vc < s->left || vc > s->right) { continue; } int v = N(vr, vc); if (visited[v]) { continue; } int alt = mind[u] + length[v]; if (alt < mind[v]) { mind[v] = alt; assert(num_queue < MAX_N * MAX_M * 4); queue[num_queue++] = HEAP_KEY(alt, v); push_heap(queue, num_queue); } } } } void free_node(struct node *root) { if (!root) { return; } free_node(root->child[0]); free_node(root->child[1]); free(root); } struct node *alloc_node(int depth, int left, int right) { struct node *s = calloc(sizeof(struct node), 1); s->depth = depth; s->left = left; s->right = right; s->mid = s->left + (s->right - s->left) / 2; for (int i = 0; i < n; i++) { dijkstra(s, i, N(i, s->mid)); } return s; } int mind_r(struct node *s, int r1, int c1, int r2, int c2) { int min = INT_MAX; for (int i = 0; i < n; i++) { int *mind = dist[s->depth][i]; int d = mind[N(r1, c1)] + mind[N(r2, c2)] - length[N(i, s->mid)]; min = MIN(min, d); } if (c1 <= s->mid && c2 >= s->mid) { return min; } else if (c2 < s->mid) { if (!s->child[0]) { s->child[0] = alloc_node(s->depth+1, s->left, s->mid-1); } int lmin = mind_r(s->child[0], r1, c1, r2, c2); return MIN(min, lmin); } else { if (!s->child[1]) { s->child[1] = alloc_node(s->depth+1, s->mid+1, s->right); } int rmin = mind_r(s->child[1], r1, c1, r2, c2); return MIN(min, rmin); } } int mind(int r1, int c1, int r2, int c2) { if (!root) { root = alloc_node(0, 0, m-1); } return mind_r(root, r1, c1, r2, c2); } int main() { scanf("%d %d", &n, &m); for (int i = 0; i < n * m; i++) { scanf("%d", &length[i]); } int q; scanf("%d", &q); for (int i = 0; i < q; i++) { int r1, c1, r2, c2; scanf("%d %d %d %d", &r1, &c1, &r2, &c2); if (c1 > c2) { int tmp = r1; r1 = r2; r2 = tmp; tmp = c1; c1 = c2; c2 = tmp; } printf("%dn", mind(r1, c1, r2, c2)); } free_node(root); return 0; } {“mode”:”full”,”isActive”:false} algorithm coding problems