Josephus Problem(或Josephus permutation)是一个与某个计数游戏相关的理论问题。
人们站在一个等待被处决的圈子里。数数 从圆圈的第一个点开始,围绕圆圈前进 顺时针方向。在指定数量的人之后 跳过,下一个人被执行。重复该过程 剩下的人,从下一个人开始,也是一样的 方向和跳过相同数量的人,直到只有一个 人仍然存在,并被释放。例如,如果n = 10那么顺序为 消除是2,4,6,8,10,3,7,1,9和5
The problem is, without simulation of the above game, try to find out the order of
elimination through means of mathematical formula or a mathematical pattern.
最初我们被给予n,即圈子中的人数。给出消除顺序,记住上述条件和约束。
简单来说,在不使用数组和链接列表等任何数据结构的情况下打印死亡模式。
答案 0 :(得分:1)
我在研究http://www.cs.man.ac.uk/~shamsbaa/Josephus.pdf后准备了解决方案。 上面的pdf中提到了这种递归。
int last_man(int n,int x)
{
if(n==1 && x==1)
return 1;
else if(n>1 && x==1)
return 2;
else if(last_man(n-1,x-1)==n-1)
return 1;
else
return last_man(n-1,x-1)+2;
}
X表示死亡的第x个人,n是最初的总人数。 将此函数循环到从1到n的x的所有值,为我们提供了elemination的顺序。
答案 1 :(得分:1)
有一种使用有序集的方法
(https://www.geeksforgeeks.org/ordered-set-gnu-c-pbds/):
代码如下:
#include <iostream>
using namespace std;
// Header files, namespaces to use
// ordered set
#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/tree_policy.hpp>
using namespace __gnu_pbds;
#define ordered_set \
tree<int, null_type, less<int>, rb_tree_tag, \
tree_order_statistics_node_update>
// Function to find the person who
// will get killed in the i'th step
void orderOfExecution(int N, int K)
{
// Create an ordered set
ordered_set V;
// Push elements in the range
// [1, N] in the set
for (int i = 1; i <= N; ++i)
V.insert(i);
// Stores the position to be removed
int pos = 0;
// Iterate until the size of the set
// is greater than 1
while (V.size() > 1) {
// Update the position
pos = (pos + K) % (int)V.size();
// Print the removed element
cout << *(V.find_by_order(pos)) << ' ';
// Erase it from the ordered set
V.erase(*(V.find_by_order(pos)));
// Update position
pos %= (int)V.size();
}
// Print the first element of the set
cout << *(V.find_by_order(0));
}
int main()
{
int N = 5, K = 2;
// Function Call
orderOfExecution(N, K);
return 0;
}
时间复杂度:O(N * log(N))
为了更好地理解,我建议您观看此视频:
答案 2 :(得分:0)
function josIterative(n, k) {
let queue = [];
for (let i = 1; i <= n; i++) queue.push(i);
let deathOrder = [];
while (queue.length !== 1) {
for (let skip = 1; skip < k; skip++) queue.push(queue.shift());
deathOrder.push(queue.shift());
}
console.log("Death order is " + deathOrder.join(" "));
return queue[0]; //survivor
}
console.log(josIterative(7, 3) + " is survivor");
该程序用javascript es6编写。 队列要注意保持新位置 另一种方法是使用递归关系来解决