【问题标题】:Josephus Algorithm约瑟夫斯算法
【发布时间】:2015-07-27 15:33:55
【问题描述】:

我正在阅读Josephus Problem 的算法。

我遇到了以下算法:

int josephusIteration(int n,int k) {
    int a=1;
    for(int i=1;i<=n;i++) {
        a=(a+k-1)%i+1;
    }
    return a;
}

我无法理解它的逻辑。假设 n=5 和 k=2。

i=1, a=1
i=2, a=1
i=3, a=3
i=4, a=1
i=5, a=3

谁能举个例子解释一下?

【问题讨论】:

  • 您在理解约瑟夫斯问题方面是否有问题,或者您是否特别想了解这个特定的算法。我问是因为它有一个更容易理解的递归解决方案。
  • 我在理解问题本身时遇到了问题。我的意思是为什么它不断地服用%i?每次迭代代表什么?
  • i 表示当您从只剩下一个人到原始总数的点向后计算时活着的人数。非递归解决方案的关键是通过执行向后工作。模 i 是因为我们在每一步都有一个圆圈,并计算圆圈周围的 k 个位置。 a 代表幸存者在圈子内的位置。
  • @RichaTibrewal 阅读下面我的回答,了解约瑟夫斯问题的递归解决方案。如果您不完全理解,请告诉我。

标签: c++ c algorithm josephus


【解决方案1】:

如果n = 5k = 2,则安全位置为3。首先,位置 2 的人被杀死,然后位置 4 的人被杀死,然后位置 1 的人被杀死。最后,位置 5 的人被杀死。所以位置 3 的人活了下来。

我已阅读您的代码,但我想在下面提出一个更易于理解的递归解决方案。

// this function returns the position of the person alive
int josephus(int n, int k)
{
  if (n == 1)
    return 1;
  else
    /* The position returned by josephus(n - 1, k) is adjusted because the
       recursive call josephus(n - 1, k) considers the original position 
       k%n + 1 as position 1 */
    return (josephus(n - 1, k) + k-1) % n + 1;
}

第一个人(从开始的第k个)被杀后,剩下n-1个人。所以我们调用josephus(n – 1, k) 来获得n-1 人的职位。

但是josephus(n – 1, k) 返回的位置会从位置 1 再次考虑。所以我们将k-1 添加到它,并用n 取其模数,因为有n 元素并添加1 来确定位置1-indexed 而不是 0-indexed

参考:http://www.geeksforgeeks.org/josephus-problem-set-1-a-on-solution/

【讨论】:

  • @BlackBird 添加了参考。我已经添加到网站上提到的解释。
  • @RichaTibrewal 你需要先了解为什么我们将k-1 添加到之前的值。然后完成%i 以确保返回的值在[1, i] 范围内。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-07-20
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多