Given an n×n grid and three integers x, y, and k, a geek starts at cell [x, y]. At each move, the geek independently chooses one of the four directions - up, down, left, or right - with equal probability and moves one cell in that direction. If the geek moves outside the grid, it dies immediately.
Find the probability that the geek remains alive after exactly k moves.
Return the result as p × q-1 mod (109 + 7), where the probability is expressed as p / q and q-1 denotes the modular multiplicative inverse of q modulo 109 + 7.
Examples:
Input: n = 2, x = 1, y = 1, k = 1 Output: 500000004 Explanation: From (1, 1) on a 2×2 grid, only 2 out of 4 moves stay inside - left to (1, 0) and up to (0, 1). Probability = 2/4 = 1/2, and modular inverse of 2 mod 10^9+7 is 500000004.
Input: n = 1, x = 0, y = 0, k = 1 Output: 0 Explanation: Any move from (0, 0) on a 1×1 grid steps outside, so probability is 0.
Input: n = 3, x = 1, y = 1, k = 0 Output: 1 Explanation: With 0 moves the geek is already alive, so probability is 1.
[Naive Approach] Using Recursion – O(4^k) Time and O(k) Space
At each step, the person can move in one of 4 directions, each with probability 1/4. We recursively explore all possible paths of k steps and sum up the probabilities of paths that stay within the island.
If the current position is outside the island, return 0 (geek is dead).
If k == 0, return 1 (geek is alive at this position).
For each of the 4 directions, recursively compute the probability and multiply by 1/4, then sum all 4 results.
C++
#include<bits/stdc++.h>usingnamespacestd;intmod=1e9+7;intpower(intx,inty){intres=1;x%=mod;while(y>0){if(y&1)res=(1LL*res*x)%mod;y>>=1;x=(1LL*x*x)%mod;}returnres;}// Function to compute modular inverseintmodInverse(intn){returnpower(n,mod-2);}intsolve(intn,inti,intj,intk,intprob){// Person stepped outside the islandif(i<0||j<0||i>=n||j>=n)return0;// Person is alive after k movesif(k==0)return1;intres=0;intdirs[4][2]={{1,0},{-1,0},{0,1},{0,-1}};// Move in all 4 directions with probability 1/4for(auto&d:dirs)res=(res+(1LL*prob*solve(n,i+d[0],j+d[1],k-1,prob))%mod)%mod;returnres;}intaliveProb(intn,intx,inty,intk){intprob=modInverse(4);returnsolve(n,x,y,k,prob);}intmain(){cout<<aliveProb(2,1,1,1)<<endl;return0;}
Java
classGfG{staticintmod=(int)1e9+7;staticintpower(intx,inty){intres=1;x%=mod;while(y>0){if((y&1)==1)res=(int)((1L*res*x)%mod);y>>=1;x=(int)((1L*x*x)%mod);}returnres;}// Function to compute modular inversestaticintmodInverse(intn){returnpower(n,mod-2);}staticintsolve(intn,inti,intj,intk,intprob){// Person stepped outside the islandif(i<0||j<0||i>=n||j>=n)return0;// Person is alive after k movesif(k==0)return1;intres=0;int[][]dirs={{1,0},{-1,0},{0,1},{0,-1}};// Move in all 4 directions with probability 1/4for(int[]d:dirs)res=(int)((res+(1L*prob*solve(n,i+d[0],j+d[1],k-1,prob))%mod)%mod);returnres;}staticintaliveProb(intn,intx,inty,intk){intprob=modInverse(4);returnsolve(n,x,y,k,prob);}publicstaticvoidmain(String[]args){System.out.println(aliveProb(2,1,1,1));}}
Python
mod=10**9+7defpower(x,y):res=1x%=modwhiley>0:ify&1:res=res*x%mody>>=1x=x*x%modreturnres# Function to compute modular inversedefmodInverse(n):returnpower(n,mod-2)defsolve(n,i,j,k,prob):# Person stepped outside the islandifi<0orj<0ori>=norj>=n:return0# Person is alive after k movesifk==0:return1res=0dirs=[(1,0),(-1,0),(0,1),(0,-1)]# Move in all 4 directions with probability 1/4fordi,djindirs:res=(res+prob*solve(n,i+di,j+dj,k-1,prob))%modreturnresdefaliveProb(n,x,y,k):prob=modInverse(4)returnsolve(n,x,y,k,prob)if__name__=="__main__":print(aliveProb(2,1,1,1))
C#
usingSystem;classGfG{staticintmod=(int)1e9+7;staticintpower(intx,inty){intres=1;x%=mod;while(y>0){if((y&1)==1)res=(int)((1L*res*x)%mod);y>>=1;x=(int)((1L*x*x)%mod);}returnres;}// Function to compute modular inversestaticintmodInverse(intn){returnpower(n,mod-2);}staticintsolve(intn,inti,intj,intk,intprob){// Person stepped outside the islandif(i<0||j<0||i>=n||j>=n)return0;// Person is alive after k movesif(k==0)return1;intres=0;int[,]dirs={{1,0},{-1,0},{0,1},{0,-1}};// Move in all 4 directions with probability 1/4for(intd=0;d<4;d++){intni=i+dirs[d,0],nj=j+dirs[d,1];res=(int)((res+(1L*prob*solve(n,ni,nj,k-1,prob))%mod)%mod);}returnres;}staticintaliveProb(intn,intx,inty,intk){intprob=modInverse(4);returnsolve(n,x,y,k,prob);}staticvoidMain(){Console.WriteLine(aliveProb(2,1,1,1));}}
JavaScript
letmod=1000000007n;functionpower(x,y){letres=1n;x=x%mod;while(y>0n){if(y&1n)res=res*x%mod;y>>=1n;x=x*x%mod;}returnres;}// Function to compute modular inversefunctionmodInverse(n){returnpower(n,mod-2n);}functionsolve(n,i,j,k,prob){// Person stepped outside the islandif(i<0||j<0||i>=n||j>=n)return0n;// Person is alive after k movesif(k===0)return1n;letres=0n;letdirs=[[1,0],[-1,0],[0,1],[0,-1]];// Move in all 4 directions with probability 1/4for(let[di,dj]ofdirs)res=(res+prob*solve(n,i+di,j+dj,k-1,prob))%mod;returnres;}functionaliveProb(n,x,y,k){letprob=modInverse(4n);returnNumber(solve(n,x,y,k,prob));}// Driver codeconsole.log(aliveProb(2,1,1,1));
Output
500000004
[Expected Approach] Using Tabulation with Rolling Array – O(n^2 * k) Time and O(n^2) Space
In the recursive approach, the same (i, j, step) states are recomputed multiple times leading to exponential time. Instead of fixing this with memoization which still uses O(n^2*k) space for the dp table, we observe that to compute probabilities at step s+1 we only ever need the probabilities at step s - never any earlier step. So we use two rolling arrays curr and nxt, computing forward from step 0 to k, reducing space from O(n^2*k) to O(n^2).
Initialize curr[x][y] = 1 and all other cells to 0 - geek starts at (x, y) with probability 1.
For each step, create nxt as all zeros. For each cell (i, j) in curr, distribute curr[i][j] * (1/4) to each valid neighbor in nxt.
After each step, set curr = nxt discarding the old layer.
After k steps, return sum of all values in curr.
C++
#include<bits/stdc++.h>usingnamespacestd;intmod=1e9+7;intpower(intx,inty){intres=1;x%=mod;while(y>0){if(y&1)res=(1LL*res*x)%mod;y>>=1;x=(1LL*x*x)%mod;}returnres;}// Function to compute modular inverseintmodInverse(intn){returnpower(n,mod-2);}intaliveProb(intn,intx,inty,intk){intprob=modInverse(4);// curr[i][j] = probability of being at (i,j) after current stepvector<vector<int>>curr(n,vector<int>(n,0));curr[x][y]=1;intdirs[4][2]={{1,0},{-1,0},{0,1},{0,-1}};for(intstep=0;step<k;step++){vector<vector<int>>nxt(n,vector<int>(n,0));for(inti=0;i<n;i++){for(intj=0;j<n;j++){if(!curr[i][j])continue;// Distribute probability to all 4 valid neighborsfor(auto&d:dirs){intni=i+d[0],nj=j+d[1];if(ni>=0&&ni<n&&nj>=0&&nj<n)nxt[ni][nj]=(nxt[ni][nj]+(1LL*curr[i][j]*prob)%mod)%mod;}}}curr=nxt;}// Sum probabilities of all alive positionsintres=0;for(inti=0;i<n;i++)for(intj=0;j<n;j++)res=(res+curr[i][j])%mod;returnres;}intmain(){cout<<aliveProb(2,1,1,1)<<endl;return0;}
Java
classGfG{staticintmod=(int)1e9+7;staticintpower(intx,inty){intres=1;x%=mod;while(y>0){if((y&1)==1)res=(int)((1L*res*x)%mod);y>>=1;x=(int)((1L*x*x)%mod);}returnres;}// Function to compute modular inversestaticintmodInverse(intn){returnpower(n,mod-2);}staticintaliveProb(intn,intx,inty,intk){intprob=modInverse(4);// curr[i][j] = probability of being at (i,j) after current stepint[][]curr=newint[n][n];curr[x][y]=1;int[][]dirs={{1,0},{-1,0},{0,1},{0,-1}};for(intstep=0;step<k;step++){int[][]nxt=newint[n][n];for(inti=0;i<n;i++){for(intj=0;j<n;j++){if(curr[i][j]==0)continue;// Distribute probability to all 4 valid neighborsfor(int[]d:dirs){intni=i+d[0],nj=j+d[1];if(ni>=0&&ni<n&&nj>=0&&nj<n)nxt[ni][nj]=(int)((nxt[ni][nj]+(1L*curr[i][j]*prob)%mod)%mod);}}}curr=nxt;}// Sum probabilities of all alive positionsintres=0;for(inti=0;i<n;i++)for(intj=0;j<n;j++)res=(res+curr[i][j])%mod;returnres;}publicstaticvoidmain(String[]args){System.out.println(aliveProb(2,1,1,1));}}
Python
mod=10**9+7defpower(x,y):res=1x%=modwhiley>0:ify&1:res=res*x%mody>>=1x=x*x%modreturnres# Function to compute modular inversedefmodInverse(n):returnpower(n,mod-2)defaliveProb(n,x,y,k):prob=modInverse(4)# curr[i][j] = probability of being at (i,j) after current stepcurr=[[0]*nfor_inrange(n)]curr[x][y]=1dirs=[(1,0),(-1,0),(0,1),(0,-1)]forstepinrange(k):nxt=[[0]*nfor_inrange(n)]foriinrange(n):forjinrange(n):ifnotcurr[i][j]:continue# Distribute probability to all 4 valid neighborsfordi,djindirs:ni,nj=i+di,j+djif0<=ni<nand0<=nj<n:nxt[ni][nj]=(nxt[ni][nj]+curr[i][j]*prob)%modcurr=nxt# Sum probabilities of all alive positionsreturnsum(curr[i][j]foriinrange(n)forjinrange(n))%modif__name__=="__main__":print(aliveProb(2,1,1,1))
C#
usingSystem;classGfG{staticintmod=(int)1e9+7;staticintpower(intx,inty){intres=1;x%=mod;while(y>0){if((y&1)==1)res=(int)((1L*res*x)%mod);y>>=1;x=(int)((1L*x*x)%mod);}returnres;}// Function to compute modular inversestaticintmodInverse(intn){returnpower(n,mod-2);}staticintaliveProb(intn,intx,inty,intk){intprob=modInverse(4);// curr[i][j] = probability of being at (i,j) after current stepint[,]curr=newint[n,n];curr[x,y]=1;int[,]dirs={{1,0},{-1,0},{0,1},{0,-1}};for(intstep=0;step<k;step++){int[,]nxt=newint[n,n];for(inti=0;i<n;i++){for(intj=0;j<n;j++){if(curr[i,j]==0)continue;// Distribute probability to all 4 valid neighborsfor(intd=0;d<4;d++){intni=i+dirs[d,0],nj=j+dirs[d,1];if(ni>=0&&ni<n&&nj>=0&&nj<n)nxt[ni,nj]=(int)((nxt[ni,nj]+(1L*curr[i,j]*prob)%mod)%mod);}}}curr=nxt;}// Sum probabilities of all alive positionsintres=0;for(inti=0;i<n;i++)for(intj=0;j<n;j++)res=(res+curr[i,j])%mod;returnres;}staticvoidMain(){Console.WriteLine(aliveProb(2,1,1,1));}}
JavaScript
letmod=1000000007n;functionpower(x,y){letres=1n;x=x%mod;while(y>0n){if(y&1n)res=res*x%mod;y>>=1n;x=x*x%mod;}returnres;}// Function to compute modular inversefunctionmodInverse(n){returnpower(n,mod-2n);}functionaliveProb(n,x,y,k){letprob=modInverse(4n);// curr[i][j] = probability of being at (i,j) after current stepletcurr=Array.from({length:n},()=>newArray(n).fill(0n));curr[x][y]=1n;letdirs=[[1,0],[-1,0],[0,1],[0,-1]];for(letstep=0;step<k;step++){letnxt=Array.from({length:n},()=>newArray(n).fill(0n));for(leti=0;i<n;i++){for(letj=0;j<n;j++){if(!curr[i][j])continue;// Distribute probability to all 4 valid neighborsfor(let[di,dj]ofdirs){letni=i+di,nj=j+dj;if(ni>=0&&ni<n&&nj>=0&&nj<n)nxt[ni][nj]=(nxt[ni][nj]+prob*curr[i][j])%mod;}}}curr=nxt;}// Sum probabilities of all alive positionsletres=0n;for(leti=0;i<n;i++)for(letj=0;j<n;j++)res=(res+curr[i][j])%mod;returnNumber(res);}// Driver codeconsole.log(aliveProb(2,1,1,1));