Probability of Survival

Last Updated : 16 Jun, 2026

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.

2056958344


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.

2056958345


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>
using namespace std;

int mod = 1e9 + 7;

int power(int x, int y) {
    int res = 1;
    x %= mod;
    while (y > 0) {
        if (y & 1)
            res = (1LL * res * x) % mod;
        y >>= 1;
        x = (1LL * x * x) % mod;
    }
    return res;
}

// Function to compute modular inverse
int modInverse(int n) {
    return power(n, mod - 2);
}

int solve(int n, int i, int j, int k, int prob) {

    // Person stepped outside the island
    if (i < 0 || j < 0 || i >= n || j >= n)
        return 0;

    // Person is alive after k moves
    if (k == 0)
        return 1;

    int res = 0;
    int dirs[4][2] = {{1, 0}, {-1, 0}, {0, 1}, {0, -1}};

    // Move in all 4 directions with probability 1/4
    for (auto& d : dirs)
        res = (res + (1LL * prob * solve(n, i + d[0], j + d[1], k - 1, prob)) % mod) % mod;

    return res;
}

int aliveProb(int n, int x, int y, int k) {
    int prob = modInverse(4);
    return solve(n, x, y, k, prob);
}

int main() {
    cout << aliveProb(2, 1, 1, 1) << endl;
    return 0;
}
Java
class GfG {
    static int mod = (int) 1e9 + 7;

    static int power(int x, int y) {
        int res = 1;
        x %= mod;
        while (y > 0) {
            if ((y & 1) == 1)
                res = (int)((1L * res * x) % mod);
            y >>= 1;
            x = (int)((1L * x * x) % mod);
        }
        return res;
    }

    // Function to compute modular inverse
    static int modInverse(int n) {
        return power(n, mod - 2);
    }

    static int solve(int n, int i, int j, int k, int prob) {

        // Person stepped outside the island
        if (i < 0 || j < 0 || i >= n || j >= n)
            return 0;

        // Person is alive after k moves
        if (k == 0)
            return 1;

        int res = 0;
        int[][] dirs = {{1, 0}, {-1, 0}, {0, 1}, {0, -1}};

        // Move in all 4 directions with probability 1/4
        for (int[] d : dirs)
            res = (int)((res + (1L * prob * solve(n, i + d[0], j + d[1], k - 1, prob)) % mod) % mod);

        return res;
    }

    static int aliveProb(int n, int x, int y, int k) {
        int prob = modInverse(4);
        return solve(n, x, y, k, prob);
    }

    public static void main(String[] args) {
        System.out.println(aliveProb(2, 1, 1, 1));
    }
}
Python
mod = 10**9 + 7

def power(x, y):
    res = 1
    x %= mod
    while y > 0:
        if y & 1:
            res = res * x % mod
        y >>= 1
        x = x * x % mod
    return res

# Function to compute modular inverse
def modInverse(n):
    return power(n, mod - 2)

def solve(n, i, j, k, prob):

    # Person stepped outside the island
    if i < 0 or j < 0 or i >= n or j >= n:
        return 0

    # Person is alive after k moves
    if k == 0:
        return 1

    res = 0
    dirs = [(1, 0), (-1, 0), (0, 1), (0, -1)]

    # Move in all 4 directions with probability 1/4
    for di, dj in dirs:
        res = (res + prob * solve(n, i + di, j + dj, k - 1, prob)) % mod

    return res

def aliveProb(n, x, y, k):
    prob = modInverse(4)
    return solve(n, x, y, k, prob)

if __name__ == "__main__":
    print(aliveProb(2, 1, 1, 1))
C#
using System;

class GfG {
    static int mod = (int) 1e9 + 7;

    static int power(int x, int y) {
        int res = 1;
        x %= mod;
        while (y > 0) {
            if ((y & 1) == 1)
                res = (int)((1L * res * x) % mod);
            y >>= 1;
            x = (int)((1L * x * x) % mod);
        }
        return res;
    }

    // Function to compute modular inverse
    static int modInverse(int n) {
        return power(n, mod - 2);
    }

    static int solve(int n, int i, int j, int k, int prob) {

        // Person stepped outside the island
        if (i < 0 || j < 0 || i >= n || j >= n)
            return 0;

        // Person is alive after k moves
        if (k == 0)
            return 1;

        int res = 0;
        int[,] dirs = {{1, 0}, {-1, 0}, {0, 1}, {0, -1}};

        // Move in all 4 directions with probability 1/4
        for (int d = 0; d < 4; d++) {
            int ni = i + dirs[d, 0], nj = j + dirs[d, 1];
            res = (int)((res + (1L * prob * solve(n, ni, nj, k - 1, prob)) % mod) % mod);
        }

        return res;
    }

    static int aliveProb(int n, int x, int y, int k) {
        int prob = modInverse(4);
        return solve(n, x, y, k, prob);
    }

    static void Main() {
        Console.WriteLine(aliveProb(2, 1, 1, 1));
    }
}
JavaScript
let mod = 1000000007n;

function power(x, y) {
    let res = 1n;
    x = x % mod;
    while (y > 0n) {
        if (y & 1n)
            res = res * x % mod;
        y >>= 1n;
        x = x * x % mod;
    }
    return res;
}

// Function to compute modular inverse
function modInverse(n) {
    return power(n, mod - 2n);
}

function solve(n, i, j, k, prob) {

    // Person stepped outside the island
    if (i < 0 || j < 0 || i >= n || j >= n)
        return 0n;

    // Person is alive after k moves
    if (k === 0)
        return 1n;

    let res = 0n;
    let dirs = [[1, 0], [-1, 0], [0, 1], [0, -1]];

    // Move in all 4 directions with probability 1/4
    for (let [di, dj] of dirs)
        res = (res + prob * solve(n, i + di, j + dj, k - 1, prob)) % mod;

    return res;
}

function aliveProb(n, x, y, k) {
    let prob = modInverse(4n);
    return Number(solve(n, x, y, k, prob));
}

// Driver code
console.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>
using namespace std;

int mod = 1e9 + 7;

int power(int x, int y) {
    int res = 1;
    x %= mod;
    while (y > 0) {
        if (y & 1)
            res = (1LL * res * x) % mod;
        y >>= 1;
        x = (1LL * x * x) % mod;
    }
    return res;
}

// Function to compute modular inverse
int modInverse(int n) {
    return power(n, mod - 2);
}

int aliveProb(int n, int x, int y, int k) {
    int prob = modInverse(4);

    // curr[i][j] = probability of being at (i,j) after current step
    vector<vector<int>> curr(n, vector<int>(n, 0));
    curr[x][y] = 1;

    int dirs[4][2] = {{1, 0}, {-1, 0}, {0, 1}, {0, -1}};

    for (int step = 0; step < k; step++) {
        vector<vector<int>> nxt(n, vector<int>(n, 0));
        for (int i = 0; i < n; i++) {
            for (int j = 0; j < n; j++) {
                if (!curr[i][j])
                    continue;

                // Distribute probability to all 4 valid neighbors
                for (auto& d : dirs) {
                    int ni = 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 positions
    int res = 0;
    for (int i = 0; i < n; i++)
        for (int j = 0; j < n; j++)
            res = (res + curr[i][j]) % mod;

    return res;
}

int main() {
    cout << aliveProb(2, 1, 1, 1) << endl;
    return 0;
}
Java
class GfG {
    static int mod = (int) 1e9 + 7;

    static int power(int x, int y) {
        int res = 1;
        x %= mod;
        while (y > 0) {
            if ((y & 1) == 1)
                res = (int)((1L * res * x) % mod);
            y >>= 1;
            x = (int)((1L * x * x) % mod);
        }
        return res;
    }

    // Function to compute modular inverse
    static int modInverse(int n) {
        return power(n, mod - 2);
    }

    static int aliveProb(int n, int x, int y, int k) {
        int prob = modInverse(4);

        // curr[i][j] = probability of being at (i,j) after current step
        int[][] curr = new int[n][n];
        curr[x][y] = 1;

        int[][] dirs = {{1, 0}, {-1, 0}, {0, 1}, {0, -1}};

        for (int step = 0; step < k; step++) {
            int[][] nxt = new int[n][n];
            for (int i = 0; i < n; i++) {
                for (int j = 0; j < n; j++) {
                    if (curr[i][j] == 0)
                        continue;

                    // Distribute probability to all 4 valid neighbors
                    for (int[] d : dirs) {
                        int ni = 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 positions
        int res = 0;
        for (int i = 0; i < n; i++)
            for (int j = 0; j < n; j++)
                res = (res + curr[i][j]) % mod;

        return res;
    }

    public static void main(String[] args) {
        System.out.println(aliveProb(2, 1, 1, 1));
    }
}
Python
mod = 10**9 + 7

def power(x, y):
    res = 1
    x %= mod
    while y > 0:
        if y & 1:
            res = res * x % mod
        y >>= 1
        x = x * x % mod
    return res

# Function to compute modular inverse
def modInverse(n):
    return power(n, mod - 2)

def aliveProb(n, x, y, k):
    prob = modInverse(4)

    # curr[i][j] = probability of being at (i,j) after current step
    curr = [[0] * n for _ in range(n)]
    curr[x][y] = 1

    dirs = [(1, 0), (-1, 0), (0, 1), (0, -1)]

    for step in range(k):
        nxt = [[0] * n for _ in range(n)]
        for i in range(n):
            for j in range(n):
                if not curr[i][j]:
                    continue

                # Distribute probability to all 4 valid neighbors
                for di, dj in dirs:
                    ni, nj = i + di, j + dj
                    if 0 <= ni < n and 0 <= nj < n:
                        nxt[ni][nj] = (nxt[ni][nj] + curr[i][j] * prob) % mod
        curr = nxt

    # Sum probabilities of all alive positions
    return sum(curr[i][j] for i in range(n) for j in range(n)) % mod

if __name__ == "__main__":
    print(aliveProb(2, 1, 1, 1))
C#
using System;

class GfG {
    static int mod = (int) 1e9 + 7;

    static int power(int x, int y) {
        int res = 1;
        x %= mod;
        while (y > 0) {
            if ((y & 1) == 1)
                res = (int)((1L * res * x) % mod);
            y >>= 1;
            x = (int)((1L * x * x) % mod);
        }
        return res;
    }

    // Function to compute modular inverse
    static int modInverse(int n) {
        return power(n, mod - 2);
    }

    static int aliveProb(int n, int x, int y, int k) {
        int prob = modInverse(4);

        // curr[i][j] = probability of being at (i,j) after current step
        int[,] curr = new int[n, n];
        curr[x, y] = 1;

        int[,] dirs = {{1, 0}, {-1, 0}, {0, 1}, {0, -1}};

        for (int step = 0; step < k; step++) {
            int[,] nxt = new int[n, n];
            for (int i = 0; i < n; i++) {
                for (int j = 0; j < n; j++) {
                    if (curr[i, j] == 0)
                        continue;

                    // Distribute probability to all 4 valid neighbors
                    for (int d = 0; d < 4; d++) {
                        int ni = 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 positions
        int res = 0;
        for (int i = 0; i < n; i++)
            for (int j = 0; j < n; j++)
                res = (res + curr[i, j]) % mod;

        return res;
    }

    static void Main() {
        Console.WriteLine(aliveProb(2, 1, 1, 1));
    }
}
JavaScript
let mod = 1000000007n;

function power(x, y) {
    let res = 1n;
    x = x % mod;
    while (y > 0n) {
        if (y & 1n)
            res = res * x % mod;
        y >>= 1n;
        x = x * x % mod;
    }
    return res;
}

// Function to compute modular inverse
function modInverse(n) {
    return power(n, mod - 2n);
}

function aliveProb(n, x, y, k) {
    let prob = modInverse(4n);

    // curr[i][j] = probability of being at (i,j) after current step
    let curr = Array.from({length: n}, () => new Array(n).fill(0n));
    curr[x][y] = 1n;

    let dirs = [[1, 0], [-1, 0], [0, 1], [0, -1]];

    for (let step = 0; step < k; step++) {
        let nxt = Array.from({length: n}, () => new Array(n).fill(0n));
        for (let i = 0; i < n; i++) {
            for (let j = 0; j < n; j++) {
                if (!curr[i][j])
                    continue;

                // Distribute probability to all 4 valid neighbors
                for (let [di, dj] of dirs) {
                    let ni = 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 positions
    let res = 0n;
    for (let i = 0; i < n; i++)
        for (let j = 0; j < n; j++)
            res = (res + curr[i][j]) % mod;

    return Number(res);
}

// Driver code
console.log(aliveProb(2, 1, 1, 1));

Output
500000004


Comment