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
以下是一些有趣的事实。
- 在第一轮中,所有位置均匀的人都被杀死。
- 对于第二轮,出现两种情况
- 如果n是偶数:例如n =8。在第一轮中,先杀2,然后杀4,再杀6,然后8。在第二轮中,我们在1、3、5和7的位置分别有1、3、5和7。分别是第四名
- 如果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