您的位置:首页 > 移动开发 > Swift

约瑟夫环 Python&Swift实现

2016-06-23 22:25 597 查看
Josephus问题的通解公式是

f(n,k)=((f(n-1,k)+k-1) mod n)+1,f(1,k)=1

其中f(n,k)表示n个人玩约瑟夫杀人游戏,每次报号k倍数的人被干掉的规则下最终剩下的那个人原本的标号。

假设有10个人,即n = 10,

0 1 2 3 4 5 6 7 8 9 选择 m = 3

那么第一个人出列后的序列为:

0 1 3 4 5 6 7 8 9 ,即:

3 4 5 6 7 8 9 0 1 (i)我们可以将该式转换为:

0 1 2 3 4 5 6 7 8 (ii)

那么则有 ((ii)+ 3 )% 10 = (i)

也就是说,我们求出九个人中第9次的编号,利用上式进行转换就能得到第10个人第10次的结果。

进行普遍情况的分析:

n个人(编号0…n-1),从0开始报数,报到m-1的出列,剩下的n-1个人继续从0开始报数,求胜利者的编号。

、第一个出列的人编号一定是 m%n-1, 剩下的n-1个人组成一个新的约瑟夫环(以编号为k=m%n的人开始):

原始kk+1k+2n-2n-1012k-2
新环012n-1
变换后就完全变成n-1个人报数的子问题。

假设子问题的解为x,那么根据上面这个表把x变为相应的n个人的情况。也就是求目前为x的人在n个人情况是标号为多少。x’=(x+k)%n。

同理,知道n-2个人可以推出n-1个人,知道n-3个人可以推出n-2个人….

令f[i]表示第i个人玩游戏报m退出最后胜利者的编号,最后的结果为f

递推公式:

f[1] = 0

f[i] = (f[i-1] + m) % i (i>1)

因为实际生活中编号总是从1开始,我们输出f
+ 1。

swift程序如下:

import UIKit
//实现约瑟夫环
func Josephus(total:Int, out:Int) -> Int{
let n = total
let m = out
var temp = 0    //初始化f[1] = 0
for i in 1...n {
temp = (temp + m) % i     //f[i] = (f[i-1] + m) % i
}
return temp + 1
}
let liveMan = Josephus(6, out: 2)
//output:5


Python代码:

def Josephus(total, out):
n = total; m = out
temp = 0
for i in range(1, n+1):
temp = (temp + m) % i     #f[i] = (f[i-1] + m) % i
return temp + 1

print(Josephus(6, 2))
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  python 算法