CSES Solutions Josephus Problem II (original) (raw)

Last Updated : 22 Mar, 2024

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:

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

**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:

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 > 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> 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> arr = new List<List>();

    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)

`

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