題目:0廊散,1桑滩,...,n-1這n個(gè)數(shù)字排成一個(gè)圓圈允睹,從數(shù)字0開(kāi)始每次從這個(gè)圓圈里刪除第m個(gè)數(shù)字运准。求出這個(gè)圓圈里剩下的最后一個(gè)數(shù)字幌氮。
定義函數(shù)f(n,m),表示每次在n個(gè)數(shù)字(0戳吝,1浩销,...,n-1)中每次刪除第m個(gè)數(shù)字后最后剩下的數(shù)字听哭。
在n個(gè)數(shù)字中慢洋,假設(shè)第一個(gè)被刪除的數(shù)字為k,那么刪除k之后剩下的n-1個(gè)數(shù)字為0 ~ k-1陆盘,k+1 ~ n-1普筹,并且下一次刪除從數(shù)字k 1開(kāi)始計(jì)數(shù)。第二個(gè)序列最后剩下的數(shù)字也就是我們要求的數(shù)字隘马。于是我們對(duì)于剩下的n-1個(gè)數(shù)字重新編號(hào)太防,k+1編號(hào)為0,k 2編號(hào)為1酸员,...蜒车,0編號(hào)為n-k-1,1編號(hào)為n-k幔嗦,k-1編號(hào)為n-2酿愧,假設(shè)f(n-1, m) = x,即n-1個(gè)數(shù)中邀泉,每次刪除第m個(gè)嬉挡,最后剩下的數(shù)字編號(hào)為x,那么這個(gè)x就對(duì)應(yīng)著原序列(n個(gè)數(shù))中的編號(hào)(x + m) % n汇恤∨痈郑可以得到遞推關(guān)系:
f(n,m)=0, n=1
f(n,m)=[f(n-1,m) + m]%n, n>1
Python代碼:
#coding=utf8
'''
題目:0,1因谎,...基括,n-1這n個(gè)數(shù)字排成一個(gè)圓圈,從數(shù)字0開(kāi)始每次從這個(gè)圓圈里刪除第m個(gè)數(shù)字蓝角。求出這個(gè)圓圈里剩下的最后一個(gè)數(shù)字阱穗。
'''
def josephus(n, m):
if type(n) != type(1) or n <= 0:
raise Exception('n must be an integer(n > 0)')
if n == 1:
return 0
else:
return (josephus(n - 1, m) + m) % n
if __name__ == '__main__':
print josephus(8, 3)
print josephus(1, 2)
print josephus(0, 2)