📜  约瑟夫斯问题 |第 3 组(使用 STL)

📅  最后修改于: 2022-05-13 01:56:07.144000             🧑  作者: Mango

约瑟夫斯问题 |第 3 组(使用 STL)

给定N个人站在一个圆圈里,一个整数K。如果最初从第一个位置开始,从当前位置顺时针方向第K活着的人被杀死,然后当前位置移动到(K+1)的位置th 活着的人,并执行相同的步骤,直到只剩下一个人,任务是打印最后一个活着的人的位置。

例子:

本文的 Set 1 和 Set 2 讨论了解决此问题的不同方法。

方法 1(使用向量): 上给定的 问题被称为 约瑟夫斯的 问题。可以使用 STL 库中的递归和向量数据结构来解决该问题。请按照以下步骤解决问题:

  • 初始化一个向量,比如arr[]来存储所有人的位置。
  • 使用变量i[1, N]范围内迭代,并在每次迭代中将i附加到向量arr[]
  • 定义一个递归函数,比如RecursiveJosephus(vector:: iterator it, vectorarr),指向当前活着的人,从那里计算K个元素。
    • 如果 向量的大小, arr1,然后返回arr[0] 中的值。
    • [1, K-1]范围内迭代,然后在每次迭代中将递增1 ,如果相等,则arr。 end()然后将arr.begin()分配给
    • 现在如果指向向量arr 的最后一个元素,则弹出向量的最后一个元素arr ,然后用第(K+1)活着的人的位置更新,即arr.begin()
    • 否则,将指向的人的位置抹去。删除后,现在指向第(K+1 个人的位置。
  • 最后,完成上述步骤后,调用函数RecursiveJosephus(arr.begin(), arr)并将其返回的值打印为最后一个活着的人的位置。

下面是上述方法的实现:

C++
// C++ program for the above approach
#include 
using namespace std;
  
// Recursive auxiliary function to find
// vthe position of thevlast alive person
int RecursiveJosephus(vector& arr, int K,
                      vector::iterator it)
{
    // If size of arr is 1
    if (arr.size() == 1) {
        return arr[0];
    }
  
    // Iterate over the range [1, K-1]
    for (int i = 1; i < K; i++) {
  
        // Increment it by 1
        it++;
  
        // If it is equal to arr.end()
        if (it == arr.end()) {
  
            // Assign arr.begin() to it
            it = arr.begin();
        }
    }
  
    // If it is equal to prev(arr.end())
    if (it == prev(arr.end())) {
  
        // Assign arr.begin() to it
        it = arr.begin();
  
        // Remove the last element
        arr.pop_back();
    }
    else {
  
        // Erase the element at it
        arr.erase(it);
    }
  
    // Return the last alive person
    return RecursiveJosephus(arr, K, it);
}
  
// Function to find the position of the
// last alive person
int Josephus(int N, int K)
{
    // Stores positions of every person
    vector arr;
    for (int i = 1; i <= N; i++)
        arr.push_back(i);
  
    // Function call to find the position
    // of the last alive person
    return RecursiveJosephus(arr, K, arr.begin());
}
  
// Driver Code
int main()
{
    // Given Input
    int N = 5;
    int K = 2;
  
    // Function Call
    cout << Josephus(N, K);
}


C++
// C++ program for the above approach
#include 
using namespace std;
  
// Recursive auxiliary function to find
// the position of the last alive person
int RecursiveJosephus(set& arr, int K,
                      set::iterator it)
{
  
    // If size of arr is 1
    if (arr.size() == 1) {
        return *it;
    }
  
    // Iterate over the range [1, K-1]
    for (int i = 1; i < K; i++) {
  
        // Increment it by 1
        it++;
  
        // If it is equal to arr.end()
        if (it == arr.end()) {
  
            // Assign arr.begin() to it
            it = arr.begin();
        }
    }
  
    // If it is equal to prev(arr.end())
    if (it == prev(arr.end())) {
  
        // Assign arr.begin() to it
        it = arr.begin();
  
        // Remove the last element
        arr.erase(prev(arr.end()));
    }
    else {
  
        // Stores the value pointed
        // by next iterator of it
        int val = (*next(it));
  
        // Erase the element at it
        arr.erase(it);
  
        // Update it
        it = arr.find(val);
    }
  
    // Return the position of
    // the last alive person
    return RecursiveJosephus(arr, K, it);
}
  
// Function to find the position
// of the last alive person
int Josephus(int N, int K)
{
    // Stores all the persons
    set arr;
  
    for (int i = 1; i <= N; i++)
        arr.insert(i);
  
    // Function call to find the position
    // of the last alive person
    return RecursiveJosephus(arr, K, arr.begin());
}
  
// Driver Code
int main()
{
    // Given Input
    int N = 5;
    int K = 2;
  
    // Function Call
    cout << Josephus(N, K);
}


输出
3

时间复杂度: O(N 2 )
辅助空间: O(N)

方法 2(使用 SET):可以使用递归和 STL 库中的集合数据结构来解决问题。请按照以下步骤解决问题:

  • 初始化一个集合,比如arr来存储所有人的位置。
  • 使用变量i[1, N]范围内迭代,并在每次迭代中将i插入集合arr中。
  • 定义一个递归函数,比如RecursiveJosephus(set::iterator it, setarr),指向当前活着的人的位置,从那里计算K个元素。
    • 如果 集合arr的大小为1,然后返回迭代器指向的值it。
    • [1, K-1]范围内迭代,然后在每次迭代中将递增1 ,如果它等于arr。 end(),然后分配arr.begin()
    • 现在,如果指向集合的最后一个元素arr的位置,则删除集合的最后一个元素arr然后 (K+1) 个人的位置arr.begin()。
    • 否则,将的下一个迭代器的值存储在一个变量中,比如val然后擦除指向的位置。
    • 删除失效。因此,现在在集合arr中找到val的值,然后将其分配给。现在指向第(K+1)活人的位置。
  • 最后,完成上述步骤后,调用函数RecursiveJosephus(arr.begin(), arr)并将其返回的值打印为最后一个活人的位置。

下面是上述方法的实现:

C++

// C++ program for the above approach
#include 
using namespace std;
  
// Recursive auxiliary function to find
// the position of the last alive person
int RecursiveJosephus(set& arr, int K,
                      set::iterator it)
{
  
    // If size of arr is 1
    if (arr.size() == 1) {
        return *it;
    }
  
    // Iterate over the range [1, K-1]
    for (int i = 1; i < K; i++) {
  
        // Increment it by 1
        it++;
  
        // If it is equal to arr.end()
        if (it == arr.end()) {
  
            // Assign arr.begin() to it
            it = arr.begin();
        }
    }
  
    // If it is equal to prev(arr.end())
    if (it == prev(arr.end())) {
  
        // Assign arr.begin() to it
        it = arr.begin();
  
        // Remove the last element
        arr.erase(prev(arr.end()));
    }
    else {
  
        // Stores the value pointed
        // by next iterator of it
        int val = (*next(it));
  
        // Erase the element at it
        arr.erase(it);
  
        // Update it
        it = arr.find(val);
    }
  
    // Return the position of
    // the last alive person
    return RecursiveJosephus(arr, K, it);
}
  
// Function to find the position
// of the last alive person
int Josephus(int N, int K)
{
    // Stores all the persons
    set arr;
  
    for (int i = 1; i <= N; i++)
        arr.insert(i);
  
    // Function call to find the position
    // of the last alive person
    return RecursiveJosephus(arr, K, arr.begin());
}
  
// Driver Code
int main()
{
    // Given Input
    int N = 5;
    int K = 2;
  
    // Function Call
    cout << Josephus(N, K);
}
输出
3

时间复杂度: O(N*K+N*log(N))
辅助空间: O(N)