📜  约瑟夫斯问题|集合2(k = 2时的简单解决方案)

📅  最后修改于: 2021-05-06 19:20:59             🧑  作者: Mango

n人围成一圈等待执行。计数从圆的某个点开始,然后沿固定的方向围绕圆进行。在每个步骤中,将跳过一定数量的人员,然后执行下一个人员。消灭围绕圈进行(随着被处决者的撤离,圈变得越来越小),直到只有最后一个剩下的人被赋予了自由。给定总人数n和数字k,表示跳过k-1个人,第k个人被圈杀。我们的任务是选择第一个圆圈中的位置,以便您成为最后一个剩下的人,从而生存下来。
我们已经在下面的集合1中讨论了一个广义的解决方案。
约瑟夫斯问题|集合1(AO(n)解)
在这篇文章中,讨论了一种特殊情况,当k = 2时

例子 :

Input  : n = 5
Output : The person at position 3 survives
Explanation : Firstly, the person at position 2 is killed, 
then at 4, then at 1 is killed. Finally, the person at 
position 5 is killed. So the person at position 3 survives.

Input  : n = 14
Output : The person at position 13 survives

以下是一些有趣的事实。

  • 在第一轮中,所有位置均匀的人都被杀死。
  • 对于第二轮,出现两种情况
    1. 如果n是偶数:例如n =8。在第一轮中,先杀2,然后杀4,再杀6,然后8。在第二轮中,我们在1、3、5和7的位置分别有1、3、5和7。分别是第四名
    2. 如果n是奇数:例如n =7。在第一个回合中,第一个2被杀死,然后是4,然后是6。在第二个回合中,我们分别在位置1st,2nd和3rd拥有3、5、7。

如果n为偶数,并且某人在当前回合中处于x位置,则该人在前一回合中处于2x – 1位置。
如果n为奇数,并且某人在当前回合中处于x位置,则该人在前一回合中处于2x +1位置。
根据以上事实,我们可以递归定义寻找幸存者位置的公式。

Let f(n) be position of survivor for input n, 
the value of f(n) can be recursively written 
as below.

If n is even
   f(n) = 2f(n/2) - 1
Else
   f(n) = 2f((n-1)/2) + 1

以上复发的解决方案是

f(n) = 2(n - 2floor(Log2n) + 1
     = 2n - 21 + floor(Log2n) + 1

以下是查找上述公式的值的实现。

C++
// C/C++ program to find solution of Josephus
// problem when size of step is 2.
#include 
 
// Returns position of survivor among a circle
// of n persons and every second person being
// killed
int josephus(int n)
{
    // Find value of 2 ^ (1 + floor(Log n))
    // which is a power of 2 whose value
    // is just above n.
    int p = 1;
    while (p <= n)
        p *= 2;
 
    // Return 2n - 2^(1+floor(Logn)) + 1
    return (2 * n) - p + 1;
}
 
// Driver Program to test above function
int main()
{
    int n = 16;
    printf("The chosen place is %d", josephus(n));
    return 0;
}


Java
// Java program to find solution of Josephus
// problem when size of step is 2.
import java.io.*;
 
class GFG {
 
    // Returns position of survivor among
    // a circle of n persons and every
    // second person being killed
    static int josephus(int n)
    {
 
        // Find value of 2 ^ (1 + floor(Log n))
        // which is a power of 2 whose value
        // is just above n.
        int p = 1;
        while (p <= n)
            p *= 2;
 
        // Return 2n - 2^(1+floor(Logn)) + 1
        return (2 * n) - p + 1;
    }
 
    // Driver Program to test above function
    public static void main(String[] args)
    {
        int n = 16;
 
        System.out.println("The chosen place is "
                           + josephus(n));
    }
}
 
// This Code is Contributed by Anuj_67


Python3
# Python3 program to find solution of
# Josephus problem when size of step is 2.
 
# Returns position of survivor among a
# circle of n persons and every second
# person being killed
def josephus(n):
     
    # Find value of 2 ^ (1 + floor(Log n))
    # which is a power of 2 whose value
    # is just above n.
    p = 1
    while p <= n:
        p *= 2
 
    # Return 2n - 2^(1 + floor(Logn)) + 1
    return (2 * n) - p + 1
 
# Driver Code
n = 16
print ("The chosen place is", josephus(n))
 
# This code is contributed by Shreyanshi Arun.


C#
// C# program to find solution of Josephus
// problem when size of step is 2.
using System;
 
class GFG {
 
    // Returns position of survivor among
    // a circle of n persons and every
    // second person being killed
    static int josephus(int n)
    {
 
        // Find value of 2 ^ (1 + floor(Log n))
        // which is a power of 2 whose value
        // is just above n.
        int p = 1;
        while (p <= n)
            p *= 2;
 
        // Return 2n - 2^(1+floor(Logn)) + 1
        return (2 * n) - p + 1;
    }
 
    // Driver Program to test above function
    static void Main()
    {
        int n = 16;
 
        Console.Write("The chosen place is "
                      + josephus(n));
    }
}
 
// This Code is Contributed by Anuj_67


PHP


Javascript


C++
// C++ program to find solution of Josephus
// problem when size of step is 2.
#include 
 
using namespace std;
 
// Returns position of survivor among a circle
// of n persons and every second person being
// killed
int josephus(int n)
{
    // An interesting observation is that
    // for every number of power of two
    // answer is 1 always.
    if (!(n & (n - 1)) && n) {
        return 1;
    }
 
    // The trick is just to right rotate the
    // binary representation of n once.
    // Find whether the number shed off
    // during left shift is set or not
 
    bitset<64> Arr(n);
 
    // shifting the bitset Arr
    // f will become true once leftmost
    // set bit is found
    bool f = false;
    for (int i = 63; i >= 0; --i) {
        if (Arr[i] == 1 && !f) {
            f = true;
            Arr[i] = Arr[i - 1];
        }
        if (f) {
 
            // shifting bits
            Arr[i] = Arr[i - 1];
        }
    }
 
    Arr[0] = 1;
 
    int res;
 
    // changing bitset to int
    res = (int)(Arr.to_ulong());
    return res;
}
 
// Driver Program to test above function
int main()
{
    int n = 16;
    printf("The chosen place is %d", josephus(n));
    return 0;
}


输出:
The chosen place is 1

可以根据观察得出k = 2时该问题的另一种有趣的解决方案,我们只需要向左旋转N的二进制表示形式即可获得所需的答案。的工作代码
下面考虑数字为64位数字提供相同的功能。

下面是上述方法的实现:

C++

// C++ program to find solution of Josephus
// problem when size of step is 2.
#include 
 
using namespace std;
 
// Returns position of survivor among a circle
// of n persons and every second person being
// killed
int josephus(int n)
{
    // An interesting observation is that
    // for every number of power of two
    // answer is 1 always.
    if (!(n & (n - 1)) && n) {
        return 1;
    }
 
    // The trick is just to right rotate the
    // binary representation of n once.
    // Find whether the number shed off
    // during left shift is set or not
 
    bitset<64> Arr(n);
 
    // shifting the bitset Arr
    // f will become true once leftmost
    // set bit is found
    bool f = false;
    for (int i = 63; i >= 0; --i) {
        if (Arr[i] == 1 && !f) {
            f = true;
            Arr[i] = Arr[i - 1];
        }
        if (f) {
 
            // shifting bits
            Arr[i] = Arr[i - 1];
        }
    }
 
    Arr[0] = 1;
 
    int res;
 
    // changing bitset to int
    res = (int)(Arr.to_ulong());
    return res;
}
 
// Driver Program to test above function
int main()
{
    int n = 16;
    printf("The chosen place is %d", josephus(n));
    return 0;
}
输出:
The chosen place is 1