Open In App

CSES Solutions – Josephus Queries

Last Updated : 28 Apr, 2024
Improve
Improve
Like Article
Like
Save
Share
Report

Consider a game where there are n children (numbered 1,2,…n) in a circle. During the game, every second child is removed from the circle, until there are no children left.

Your task is to process q queries of the form: “when there are n children, who is the kth child that will be removed?”

Example:

Input: totalChildren = 7, kthChild = 1;
Output: 2
Explanation:

  • Initial children: 1 2 3 4 5 6 7
  • After 1st removal: 2 is removed

Input: totalChildren = 7, kthChild = 3;
Output: 6
Explanation:

  • Initial children: 1 2 3 4 5 6 7
  • After 1st removal: 2 is removed
  • After 2nd removal: 4 is removed
  • After 3rd removal: 6 is removed

Approach:

The idea is to use a recursive function let say calculateRemovedChild () to solve the problem.

  • Base Case: If there’s only one child left, that child is the one to be removed.
  • Recursive Case: If the round number kthChild is less than or equal to half the total number of children, then calculates which child will be removed in that round. If kthChild is more than half the total number of children, calls the function itself recursively with half the total number of children and adjusts kthChild accordingly.

Steps to solve this problem:

  • Base Case:
    • If there’s only one child (totalChildren == 1), return 1, as that child is the one to be removed.
  • If kthChild is less than or equal to half the total number of children:
    • If doubling kthChild exceeds the total number of children, return the remainder of 2 * kthChild divided by the total number of children.
    • Otherwise, return 2 * kthChild.
  • If kthChild is greater than half the total number of children:
    • Recursively calculate the kth child to be removed for half the total number of children and store it in temp.
    • If the total number of children is odd, return 2 * temp + 1.
    • Otherwise, return 2 * temp – 1.

Code:

Below is the C++ implementation of the above approach:

C++
#include <iostream>
using namespace std;

// Function to calculate the kth child to be removed
long long calculateRemovedChild(long long totalChildren,
                                long long kthChild)
{
    // Base case: if there's only one child left, it's the
    // one to be removed
    if (totalChildren == 1)
        return 1;
    // If k is less than or equal to half the total number
    // of children
    if (kthChild <= (totalChildren + 1) / 2)
    {
        // If 2*k is greater than the total number of
        // children, return the remainder of 2*k divided by
        // the total number of children
        if (2 * kthChild > totalChildren)
            return (2 * kthChild) % totalChildren;
        else
            // Otherwise, return 2*k
            return 2 * kthChild;
    }
    // Calculate the kth child to be removed for half the
    // total number of children
    long long temp = calculateRemovedChild(
        totalChildren / 2,
        kthChild - (totalChildren + 1) / 2);
    // If the total number of children is odd, return 2*temp
    // + 1
    if (totalChildren % 2 == 1)
        return 2 * temp + 1;
    // Otherwise, return 2*temp - 1
    return 2 * temp - 1;
}

int main()
{
      long long totalChildren, kthChild;
  
      // Example 1
      totalChildren = 7;
      kthChild = 1;
    cout << calculateRemovedChild(totalChildren, kthChild)
             << "\n";
  
      // Example 2
      totalChildren = 7;
      kthChild = 3;
    cout << calculateRemovedChild(totalChildren, kthChild)
             << "\n";
}
Java
public class RemovedChildCalculator {
    // Function to calculate the kth child to be removed
    public static long calculateRemovedChild(long totalChildren, long kthChild) {
        // Base case: if there's only one child left, it's the one to be removed
        if (totalChildren == 1)
            return 1;
        // If k is less than or equal to half the total number of children
        if (kthChild <= (totalChildren + 1) / 2) {
            // If 2*k is greater than the total number of children, return the remainder of 2*k divided by the total number of children
            if (2 * kthChild > totalChildren)
                return (2 * kthChild) % totalChildren;
            else
                // Otherwise, return 2*k
                return 2 * kthChild;
        }
        // Calculate the kth child to be removed for half the total number of children
        long temp = calculateRemovedChild(totalChildren / 2, kthChild - (totalChildren + 1) / 2);
        // If the total number of children is odd, return 2*temp + 1
        if (totalChildren % 2 == 1)
            return 2 * temp + 1;
        // Otherwise, return 2*temp - 1
        return 2 * temp - 1;
    }

    public static void main(String[] args) {
        long totalChildren, kthChild;

        // Example 1
        totalChildren = 7;
        kthChild = 1;
        System.out.println(calculateRemovedChild(totalChildren, kthChild));

        // Example 2
        totalChildren = 7;
        kthChild = 3;
        System.out.println(calculateRemovedChild(totalChildren, kthChild));
    }
}

// This code is contributed by shivamgupta0987654321
Python3
def calculate_removed_child(total_children, kth_child):
    # Base case: if there's only one child left, it's the one to be removed
    if total_children == 1:
        return 1

    # If k is less than or equal to half the total number of children
    if kth_child <= (total_children + 1) // 2:
        # If 2*k is greater than the total number of children,
        # return the remainder of 2*k divided by the total number of children
        if 2 * kth_child > total_children:
            return (2 * kth_child) % total_children
        else:
            # Otherwise, return 2*k
            return 2 * kth_child

    # Calculate the kth child to be removed for half the total number of children
    temp = calculate_removed_child(total_children // 2, kth_child - (total_children + 1) // 2)

    # If the total number of children is odd, return 2*temp + 1
    if total_children % 2 == 1:
        return 2 * temp + 1
    # Otherwise, return 2*temp - 1
    return 2 * temp - 1

if __name__ == "__main__":
    # Example 1
    total_children = 7
    kth_child = 1
    print(calculate_removed_child(total_children, kth_child))

    # Example 2
    total_children = 7
    kth_child = 3
    print(calculate_removed_child(total_children, kth_child))
JavaScript
function calculateRemovedChild(totalChildren, kthChild) {
    // Base case: if there's only one child left, it's the one to be removed
    if (totalChildren === 1) {
        return 1;
    }

    // If k is less than or equal to half the total number of children
    if (kthChild <= Math.floor((totalChildren + 1) / 2)) {
        // If 2*k is greater than the total number of children,
        // return the remainder of 2*k divided by the total number of children
        if (2 * kthChild > totalChildren) {
            return (2 * kthChild) % totalChildren;
        } else {
            // Otherwise, return 2*k
            return 2 * kthChild;
        }
    }

    // Calculate the kth child to be removed for half the total number of children
    const temp = calculateRemovedChild(Math.floor(totalChildren / 2), kthChild - Math.floor((totalChildren + 1) / 2));

    // If the total number of children is odd, return 2*temp + 1
    if (totalChildren % 2 === 1) {
        return 2 * temp + 1;
    }
    // Otherwise, return 2*temp - 1
    return 2 * temp - 1;
}

// Example 1
let totalChildren = 7;
let kthChild = 1;
console.log(calculateRemovedChild(totalChildren, kthChild));

// Example 2
totalChildren = 7;
kthChild = 3;
console.log(calculateRemovedChild(totalChildren, kthChild));

Output
2
6

Time Complexity: O(log(totalChildren)).
Auxiliary Space: O(log(totalChildren)).



Like Article
Suggest improvement
Previous
Next
Share your thoughts in the comments

Similar Reads