Minimize steps for Knight to collect maximum points (Knight in Geekland)

Last Updated : 22 Aug, 2026

A knight is stationed at position (x, y) in Geekland, represented as an n×m matrix, where each cell holds some points.

  • At the i-th step, the knight can collect the total points from all cells reachable in exactly i knight-moves (moving the same way a knight moves on a chessboard), without revisiting any cell.
  • The knight also has a magical power to pull points from the future: if he collects y points at step x, he can absorb all the points collectable at step (x + y) as well, without spending an additional step.
  • If step (x + y) itself yields z points, he can further absorb step (x + y + z), and so on, while always remaining at step x and collecting the cumulative total of every step reachable this way.

Find the minimum step count that yields the maximum total points collectable this way.

Note: The knight moves exactly like a knight on a chessboard. Indexing is 0-based.

Examples:

Input: x = 2, y = 1, mat[][] = [[7,6,8], [9,1,4], [6,2,8]]
Output: 0
Explanation:

2056958537

At step 0, the knight is at (2,1) and has collected 2 points, the value of its own cell.
At step 1, the knight can reach cells (0,0) and (0,2) in a single knight-move, worth 7 and 8 points, totaling 15.
At step 2, cells (1,0) and (1,2) become reachable, worth 9 and 4 points, totaling 13.
Since the knight has 2 points at step 0, its magical power lets it absorb step (0+2)=2's points as well, adding 13 to its total and giving 2+13=15 points, all while still standing at step 0.
At step 1 alone, the knight already has 15 points, matching step 0's combined total.
Since both step 0 and step 1 reach the same maximum of 15 points, and the problem asks for the smallest step count that achieves the maximum, the answer is 0.

Input: x = 0, y = 2, mat[][] = [[1,1,2,1,1], [1,3,1,3,1], [2,1,1,1,2], [1,3,1,3,1]]
Output: 0
Explanation: The step-wise points are [2, 4, 15, 6, 4] for steps 0 through 4. At step 0, the knight collects 2 points and uses his magical power to jump to step (0+2)=2, collecting 15 more points, for a total of 17 - the maximum achievable, reached at the smallest step count of 0.

Try It Yourself
redirect icon

BFS Layering with Jump-Chain Aggregation - O(n*m) Time and O(n*m) Space

The idea is to perform a BFS from the knight's starting position to group cells by their minimum knight-move distance and compute the total points collected at each step. Then process these step totals from right to left to aggregate all points obtainable through the magical jump chain and return the earliest step with the maximum total.

  • Perform a BFS from the starting cell using knight moves, where each BFS level represents cells reachable in exactly that many moves.
  • Compute the total points of all cells in every BFS level and store them according to their corresponding step.
  • Traverse the step totals from the last step towards the first so that the result of every future jump is already available.
  • For each step, if jumping ahead by its collected points lands on a valid step, add the already aggregated points of that destination step.
  • Repeat this process until every step stores the maximum points obtainable when starting from that step.
  • Traverse the final aggregated values and return the smallest step number having the maximum total points.
C++
#include <bits/stdc++.h>
using namespace std;

int dx[8] = {-2, -1, 1, 2, 2, 1, -1, -2};
int dy[8] = {1, 2, 2, 1, -1, -2, -2, -1};

bool isSafe(int i, int j, int n, int m) {
    return i >= 0 && i < n && j >= 0 && j < m;
}

int knightInGeekland(int x, int y, vector<vector<int>> &mat) {
    int n = mat.size();
    int m = mat[0].size();

    vector<vector<bool>> visited(n, vector<bool>(m, false));
    visited[x][y] = true;

    queue<pair<int, int>> q;
    q.push({x, y});

    vector<int> pointsPerStep;

    // collect total points reachable at each successive knight-move step
    while (!q.empty()) {
        int size = q.size();
        int points = 0;

        for (int i = 0; i < size; i++) {
            auto [cx, cy] = q.front();
            q.pop();
            points += mat[cx][cy];

            for (int k = 0; k < 8; k++) {
                int nx = cx + dx[k];
                int ny = cy + dy[k];

                if (isSafe(nx, ny, n, m) && !visited[nx][ny]) {
                    visited[nx][ny] = true;
                    q.push({nx, ny});
                }
            }
        }

        pointsPerStep.push_back(points);
    }

    // apply the magical power: jump forward by the collected points at each step
    for (int i = pointsPerStep.size() - 1; i >= 0; i--) {
        if (i + pointsPerStep[i] < (int)pointsPerStep.size())
            pointsPerStep[i] = pointsPerStep[i] + pointsPerStep[i + pointsPerStep[i]];
    }

    // find the smallest step achieving the maximum total
    int maxPoints = -1, ans = -1;
    for (int i = 0; i < (int)pointsPerStep.size(); i++) {
        if (pointsPerStep[i] > maxPoints) {
            maxPoints = pointsPerStep[i];
            ans = i;
        }
    }

    return ans;
}

int main() {
    int x = 0, y = 2;
    vector<vector<int>> mat = {
        {1, 1, 2, 1, 1},
        {1, 3, 1, 3, 1},
        {2, 1, 1, 1, 2},
        {1, 3, 1, 3, 1}
    };

    cout << knightInGeekland(x, y, mat) << endl;

    return 0;
}
Java
import java.util.Queue;
import java.util.List;
import java.util.ArrayList;
import java.util.LinkedList;

class GfG {
    static int[] dx = {-2, -1, 1, 2, 2, 1, -1, -2};
    static int[] dy = {1, 2, 2, 1, -1, -2, -2, -1};

    static boolean isSafe(int i, int j, int n, int m) {
        return i >= 0 && i < n && j >= 0 && j < m;
    }

    static int knightInGeekland(int x, int y, int[][] mat) {
        int n = mat.length;
        int m = mat[0].length;

        boolean[][] visited = new boolean[n][m];
        visited[x][y] = true;

        Queue<int[]> q = new LinkedList<>();
        q.add(new int[]{x, y});

        List<Integer> pointsPerStep = new ArrayList<>();

        // collect total points reachable at each successive knight-move step
        while (!q.isEmpty()) {
            int size = q.size();
            int points = 0;

            for (int i = 0; i < size; i++) {
                int[] cell = q.poll();
                int cx = cell[0], cy = cell[1];
                points += mat[cx][cy];

                for (int k = 0; k < 8; k++) {
                    int nx = cx + dx[k];
                    int ny = cy + dy[k];

                    if (isSafe(nx, ny, n, m) && !visited[nx][ny]) {
                        visited[nx][ny] = true;
                        q.add(new int[]{nx, ny});
                    }
                }
            }

            pointsPerStep.add(points);
        }

        // apply the magical power: jump forward by the collected points at each step
        for (int i = pointsPerStep.size() - 1; i >= 0; i--) {
            int val = pointsPerStep.get(i);
            if (i + val < pointsPerStep.size())
                pointsPerStep.set(i, val + pointsPerStep.get(i + val));
        }

        // find the smallest step achieving the maximum total
        int maxPoints = -1, ans = -1;
        for (int i = 0; i < pointsPerStep.size(); i++) {
            if (pointsPerStep.get(i) > maxPoints) {
                maxPoints = pointsPerStep.get(i);
                ans = i;
            }
        }

        return ans;
    }

    public static void main(String[] args) {
        int x = 0, y = 2;
        int[][] mat = {
            {1, 1, 2, 1, 1},
            {1, 3, 1, 3, 1},
            {2, 1, 1, 1, 2},
            {1, 3, 1, 3, 1}
        };

        System.out.println(knightInGeekland(x, y, mat));
    }
}
Python
from collections import deque

def isSafe(i, j, n, m):
    return 0 <= i < n and 0 <= j < m

def knightInGeekland(x, y, mat):
    n = len(mat)
    m = len(mat[0])
    
    dx = [-2, -1, 1, 2, 2, 1, -1, -2]
    dy = [1, 2, 2, 1, -1, -2, -2, -1]

    visited = [[False] * m for _ in range(n)]
    visited[x][y] = True

    q = deque([(x, y)])
    pointsPerStep = []

    # collect total points reachable at each successive knight-move step
    while q:
        size = len(q)
        points = 0

        for _ in range(size):
            cx, cy = q.popleft()
            points += mat[cx][cy]

            for k in range(8):
                nx = cx + dx[k]
                ny = cy + dy[k]

                if isSafe(nx, ny, n, m) and not visited[nx][ny]:
                    visited[nx][ny] = True
                    q.append((nx, ny))

        pointsPerStep.append(points)

    # apply the magical power: jump forward by the collected points at each step
    for i in range(len(pointsPerStep) - 1, -1, -1):
        val = pointsPerStep[i]
        if i + val < len(pointsPerStep):
            pointsPerStep[i] = val + pointsPerStep[i + val]

    # find the smallest step achieving the maximum total
    maxPoints = -1
    ans = -1
    for i in range(len(pointsPerStep)):
        if pointsPerStep[i] > maxPoints:
            maxPoints = pointsPerStep[i]
            ans = i

    return ans

x, y = 0, 2
mat = [
    [1, 1, 2, 1, 1],
    [1, 3, 1, 3, 1],
    [2, 1, 1, 1, 2],
    [1, 3, 1, 3, 1]
]
print(knightInGeekland(x, y, mat))
C#
using System;
using System.Collections.Generic;

class GfG {
    static int[] dx = { -2, -1, 1, 2, 2, 1, -1, -2 };
    static int[] dy = { 1, 2, 2, 1, -1, -2, -2, -1 };

    static bool isSafe(int i, int j, int n, int m) {
        return i >= 0 && i < n && j >= 0 && j < m;
    }

    static int knightInGeekland(int x, int y, int[][] mat) {
        int n = mat.Length;
        int m = mat[0].Length;

        bool[,] visited = new bool[n, m];
        visited[x, y] = true;

        Queue<(int, int)> q = new Queue<(int, int)>();
        q.Enqueue((x, y));

        List<int> pointsPerStep = new List<int>();

        // collect total points reachable at each successive knight-move step
        while (q.Count > 0) {
            int size = q.Count;
            int points = 0;

            for (int i = 0; i < size; i++) {
                var (cx, cy) = q.Dequeue();
                points += mat[cx][cy];

                for (int k = 0; k < 8; k++) {
                    int nx = cx + dx[k];
                    int ny = cy + dy[k];

                    if (isSafe(nx, ny, n, m) && !visited[nx, ny]) {
                        visited[nx, ny] = true;
                        q.Enqueue((nx, ny));
                    }
                }
            }

            pointsPerStep.Add(points);
        }

        // apply the magical power: jump forward by the collected points at each step
        for (int i = pointsPerStep.Count - 1; i >= 0; i--) {
            int val = pointsPerStep[i];
            if (i + val < pointsPerStep.Count)
                pointsPerStep[i] = val + pointsPerStep[i + val];
        }

        // find the smallest step achieving the maximum total
        int maxPoints = -1, ans = -1;
        for (int i = 0; i < pointsPerStep.Count; i++) {
            if (pointsPerStep[i] > maxPoints) {
                maxPoints = pointsPerStep[i];
                ans = i;
            }
        }

        return ans;
    }

    static void Main() {
        int x = 0, y = 2;
        int[][] mat = {
            new int[]{1, 1, 2, 1, 1},
            new int[]{1, 3, 1, 3, 1},
            new int[]{2, 1, 1, 1, 2},
            new int[]{1, 3, 1, 3, 1}
        };

        Console.WriteLine(knightInGeekland(x, y, mat));
    }
}
JavaScript
function isSafe(i, j, n, m) {
    return i >= 0 && i < n && j >= 0 && j < m;
}

function knightInGeekland(x, y, mat) {
    const n = mat.length;
    const m = mat[0].length;
    
    const dx = [-2, -1, 1, 2, 2, 1, -1, -2];
    const dy = [1, 2, 2, 1, -1, -2, -2, -1];    

    const visited = Array.from({ length: n }, () => new Array(m).fill(false));
    visited[x][y] = true;

    const q = [[x, y]];
    const pointsPerStep = [];

    // collect total points reachable at each successive knight-move step
    while (q.length > 0) {
        const size = q.length;
        let points = 0;

        for (let i = 0; i < size; i++) {
            const [cx, cy] = q.shift();
            points += mat[cx][cy];

            for (let k = 0; k < 8; k++) {
                const nx = cx + dx[k];
                const ny = cy + dy[k];

                if (isSafe(nx, ny, n, m) && !visited[nx][ny]) {
                    visited[nx][ny] = true;
                    q.push([nx, ny]);
                }
            }
        }

        pointsPerStep.push(points);
    }

    // apply the magical power: jump forward by the collected points at each step
    for (let i = pointsPerStep.length - 1; i >= 0; i--) {
        const val = pointsPerStep[i];
        if (i + val < pointsPerStep.length)
            pointsPerStep[i] = val + pointsPerStep[i + val];
    }

    // find the smallest step achieving the maximum total
    let maxPoints = -1, ans = -1;
    for (let i = 0; i < pointsPerStep.length; i++) {
        if (pointsPerStep[i] > maxPoints) {
            maxPoints = pointsPerStep[i];
            ans = i;
        }
    }

    return ans;
}

// Driver Code
const x = 0, y = 2;
const mat = [
    [1, 1, 2, 1, 1],
    [1, 3, 1, 3, 1],
    [2, 1, 1, 1, 2],
    [1, 3, 1, 3, 1]
];
console.log(knightInGeekland(x, y, mat));

Output
0
Comment