Open In App

CSES Solutions – Josephus Problem II

Last Updated : 22 Mar, 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, repeatedly K children are skipped and one child is removed from the circle. In which order will the children be removed?

Examples:

Input: N = 7, K = 2
Output: 3 6 2 7 5 1 4
Explanation:

  • children = [1, 2, 3, 4, 5, 6, 7], 1 and 2 are skipped and 3 is removed.
  • children = [1, 2, 4, 5, 6, 7], 4 and 5 are skipped and 6 is removed.
  • children = [1, 2, 4, 5, 7], 7 and 1 are skipped and 2 is removed.
  • children = [1, 4, 5, 7], 4 and 5 are skipped and 7 is removed.
  • children = [1, 4, 5], 1 and 4 are skipped and 5 is removed.
  • children = [1, 4], 1 and 4 are skipped and 1 is removed.
  • children = [4], 4 is skipped and removed.

Input: N = 6, K = 1
Output: 2 4 6 3 1 5
Explanation:

  • children = [1, 2, 3, 4, 5, 6], 1 is skipped and 2 is removed.
  • children = [1, 3, 4, 5, 6], 3 is skipped and 4 is removed.
  • children = [1, 3, 5, 6], 5 is skipped and 6 is removed.
  • children = [1, 3, 5], 1 is skipped and 3 is removed.
  • children = [1, 5], 5 is skipped and 1 is removed.
  • children = [5], 5 is skipped and removed.

Approach: To solve the problem, follow the below idea:

We can solve this problem by storing the numbers in a 2D vector of which size of each inner vector is int(sqrt(N)). We will arrange all the children in rows and columns such that each row has at max sqrt(N) columns. Now, we can start from the first row and move to the next rows by making jumps of size sqrt(N) while finding the Kth child to remove. After removing the Kth child, we can again move to the next row making jumps of size sqrt(N). We can take two indices to keep track of the row and column. As soon as we reach the child to be removed, we mark the child as removed and resize the array. Also, if we exceed all the rows we start from the first row again.

Step-by-step algorithm:

  • Maintain a 2D array arr[][] which has at max sqrt(N) elements in each row.
  • Initialize row = 0 and column = 0.
  • Iterate a loop from 0 to N – 1 to keep track of the children removed.
    • Find the position of the element to be removed.
    • Move to the element to be removed by making jumps of size sqrt(N).
    • After reaching the element to be removed, remove the element and resize the row.
    • Also keep track of the row and column such that the row does not exceed the total number of rows in arr[][] and cols does not exceed the number of elements present in the row.
  • After N removals, all children are printed in order.

Below is the implementation of the algorithm:

C++
#include <bits/stdc++.h>
using namespace std;
#define ll long long
#define mod 1000000007

// Function to print the order in which children are removed
void solve(int N, int K)
{
    // 2D array to store ranges of size sqrt(N)
    vector<vector<int> > arr;

    int root = sqrt(N);
    int row = 0, col = 0, count = 0;

    // Construct the 2D vector arr
    vector<int> vec;
    for (int i = 1; i <= N; i++) {
        if (count > root) {
            count = 0;
            arr.push_back(vec);
            vec.clear();
        }
        vec.push_back(i);
        count++;
    }
    if (!vec.empty())
        arr.push_back(vec);

    // Iterate till we have removed all the children
    for (int i = 0; i < N; i++) {
        // Fnd the position of the element to be removed
        int j = K % (N - i);

        // Make jumps till we reach the position of the
        // element to be removed
        while (j) {
            // If we can jump j elements in the current row,
            // we jump to that column
            if (col + j < arr[row].size()) {
                col += j;
                j = 0;
            }
            // If we cannot jump j elements, we jump over
            // all the elements in the current row and move
            // to the next row
            else {
                j -= arr[row].size() - col;
                col = 0;
                row++;
            }
            // If all the elements are traversed, we start
            // from the first row again
            if (row >= arr.size())
                row = 0;
        }

        // While the current row has lesser columns, move to
        // the next row
        while (arr[row].size() <= col) {
            col = 0;
            row++;
            if (row >= arr.size())
                row = 0;
        }
        cout << arr[row][col] << " ";
        if (i != N - 1) {
            // Remove the student from the current row
            arr[row].erase(arr[row].begin() + col);
            while (arr[row].size() <= col) {
                col = 0;
                row++;
                if (row >= arr.size())
                    row = 0;
            }
        }
    }
}

int main()
{
    // Sample Input
    int N = 6, K = 1;

    solve(N, K);

    return 0;
}
Java
import java.util.ArrayList;

public class RemoveChildrenOrder {
    public static void solve(int N, int K) {
        // 2D array to store ranges of size sqrt(N)
        ArrayList<ArrayList<Integer>> arr = new ArrayList<>();

        int root = (int) Math.sqrt(N);
        int row = 0, col = 0, count = 0;

        // Construct the 2D vector arr
        ArrayList<Integer> vec = new ArrayList<>();
        for (int i = 1; i <= N; i++) {
            if (count > root) {
                count = 0;
                arr.add(new ArrayList<>(vec));
                vec.clear();
            }
            vec.add(i);
            count++;
        }
        if (!vec.isEmpty())
            arr.add(new ArrayList<>(vec));

        // Iterate till we have removed all the children
        for (int i = 0; i < N; i++) {
            // Find the position of the element to be removed
            int j = K % (N - i);

            // Make jumps till we reach the position of the
            // element to be removed
            while (j > 0) {
                // If we can jump j elements in the current row,
                // we jump to that column
                if (col + j < arr.get(row).size()) {
                    col += j;
                    j = 0;
                }
                // If we cannot jump j elements, we jump over
                // all the elements in the current row and move
                // to the next row
                else {
                    j -= arr.get(row).size() - col;
                    col = 0;
                    row++;
                }
                // If all the elements are traversed, we start
                // from the first row again
                if (row >= arr.size())
                    row = 0;
            }

            // While the current row has fewer columns, move to
            // the next row
            while (arr.get(row).size() <= col) {
                col = 0;
                row++;
                if (row >= arr.size())
                    row = 0;
            }
            System.out.print(arr.get(row).get(col) + " ");
            if (i != N - 1) {
                // Remove the student from the current row
                arr.get(row).remove(col);
                while (arr.get(row).size() <= col) {
                    col = 0;
                    row++;
                    if (row >= arr.size())
                        row = 0;
                }
            }
        }
    }

    public static void main(String[] args) {
        // Sample Input
        int N = 6, K = 1;

        solve(N, K);
    }
}
// This code is contributed by rambabuguphka
C#
using System;
using System.Collections.Generic;

public class ChildrenOrder
{
    // Function to print the order in which children are removed
    public static void Solve(int N, int K)
    {
        // 2D list to store ranges of size sqrt(N)
        List<List<int>> arr = new List<List<int>>();

        int root = (int)Math.Sqrt(N);
        int row = 0;
        int col = 0;
        int count = 0;

        // Construct the 2D list arr
        List<int> vec = new List<int>();
        for (int i = 1; i <= N; i++)
        {
            if (count > root)
            {
                count = 0;
                arr.Add(vec);
                vec = new List<int>();
            }
            vec.Add(i);
            count++;
        }
        if (vec.Count > 0)
        {
            arr.Add(vec);
        }

        // Iterate till we have removed all the children
        for (int i = 0; i < N; i++)
        {
            // Find the position of the element to be removed
            int j = K % (N - i);

            // Make jumps till we reach the position of the element to be removed
            while (j > 0)
            {
                // If we can jump j elements in the current row, we jump to that column
                if (col + j < arr[row].Count)
                {
                    col += j;
                    j = 0;
                }
                // If we cannot jump j elements, we jump over all the elements in the current row and move to the next row
                else
                {
                    j -= arr[row].Count - col;
                    col = 0;
                    row++;
                    if (row >= arr.Count)
                    {
                        row = 0;
                    }
                }
            }

            // While the current row has lesser columns, move to the next row
            while (arr[row].Count <= col)
            {
                col = 0;
                row++;
                if (row >= arr.Count)
                {
                    row = 0;
                }
            }

            Console.Write(arr[row][col] + " ");
            if (i != N - 1)
            {
                // Remove the student from the current row
                arr[row].RemoveAt(col);
                while (arr[row].Count <= col)
                {
                    col = 0;
                    row++;
                    if (row >= arr.Count)
                    {
                        row = 0;
                    }
                }
            }
        }
        Console.WriteLine();
    }

    public static void Main(string[] args)
    {
        // Sample Input
        int N = 6;
        int K = 1;

        Solve(N, K);
    }
}
Javascript
// Function to print the order in which children are removed
function solve(N, K) {
    // 2D array to store ranges of size sqrt(N)
    let arr = [];

    let root = Math.sqrt(N);
    let row = 0, col = 0, count = 0;

    // Construct the 2D array arr
    let vec = [];
    for (let i = 1; i <= N; i++) {
        if (count > root) {
            count = 0;
            arr.push([...vec]);
            vec = [];
        }
        vec.push(i);
        count++;
    }
    if (vec.length !== 0)
        arr.push([...vec]);

    // Iterate till we have removed all the children
    for (let i = 0; i < N; i++) {
        // Find the position of the element to be removed
        let j = K % (N - i);

        // Make jumps till we reach the position of the element to be removed
        while (j) {
            // If we can jump j elements in the current row, we jump to that column
            if (col + j < arr[row].length) {
                col += j;
                j = 0;
            }
            // If we cannot jump j elements, we jump over all the elements in the current row and move to the next row
            else {
                j -= arr[row].length - col;
                col = 0;
                row++;
            }
            // If all the elements are traversed, we start from the first row again
            if (row >= arr.length)
                row = 0;
        }

        // While the current row has fewer columns, move to the next row
        while (arr[row].length <= col) {
            col = 0;
            row++;
            if (row >= arr.length)
                row = 0;
        }
        process.stdout.write(`${arr[row][col]} `);
        if (i !== N - 1) {
            // Remove the student from the current row
            arr[row].splice(col, 1);
            while (arr[row].length <= col) {
                col = 0;
                row++;
                if (row >= arr.length)
                    row = 0;
            }
        }
    }
}

// Sample Input
const N = 6, K = 1;

solve(N, K);
Python3
import math

# Function to print the order in which children are removed
def solve(N, K):
    # 2D list to store ranges of size sqrt(N)
    arr = []

    root = int(math.sqrt(N))
    row = 0
    col = 0
    count = 0

    # Construct the 2D list arr
    vec = []
    for i in range(1, N + 1):
        if count > root:
            count = 0
            arr.append(vec)
            vec = []
        vec.append(i)
        count += 1
    if vec:
        arr.append(vec)

    # Iterate till we have removed all the children
    for i in range(N):
        # Find the position of the element to be removed
        j = K % (N - i)

        # Make jumps till we reach the position of the element to be removed
        while j:
            # If we can jump j elements in the current row, we jump to that column
            if col + j < len(arr[row]):
                col += j
                j = 0
            # If we cannot jump j elements, we jump over all the elements in the current row and move to the next row
            else:
                j -= len(arr[row]) - col
                col = 0
                row += 1
                if row >= len(arr):
                    row = 0

        # While the current row has lesser columns, move to the next row
        while len(arr[row]) <= col:
            col = 0
            row += 1
            if row >= len(arr):
                row = 0

        print(arr[row][col], end=" ")
        if i != N - 1:
            # Remove the student from the current row
            del arr[row][col]
            while len(arr[row]) <= col:
                col = 0
                row += 1
                if row >= len(arr):
                    row = 0
    print()


# Sample Input
N = 6
K = 1

solve(N, K)

Output
2 4 6 3 1 5 







Time Complexity: O(N * sqrt(N)), where N is the number of children.
Auxiliary Space: O(N)



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

Similar Reads