1.约瑟夫环问题
据说著名犹太历史学家 Josephus有过以下的故事:在罗马人占领乔塔帕特后,39 个犹太人与Josephus及他的朋友躲到一个洞中,39个犹太人决定宁愿死也不要被敌人抓到,于是决定了一个自杀方式,41个人排成一个圆圈,由第1个人开始报数,每报数到第3人该人就必须自杀,然后再由下一个重新报数,直到所有人都自杀身亡为止。然而Josephus 和他的朋友并不想遵从。首先从一个人开始,越过k-2个人(因为第一个人已经被越过),并杀掉第k个人。接着,再越过k-1个人,并杀掉第k个人。这个过程沿着圆圈一直进行,直到最终只剩下一个人留下,这个人就可以继续活着。问题是,给定了和,一开始要站在什么地方才能避免被处决?Josephus要他的朋友先假装遵从,他将朋友与自己安排在第16个与第31个位置,于是逃过了这场死亡游戏
实现代码:
#约瑟夫环问题 def josephus(n,k): link = list(range(1,n+1)) ind = 0 for loop_i in range(n-1): ind = (ind + k) % len(link) ind -= 1 print('kill:',link[ind]) del link[ind] if ind == -1: ind = 0 print("survice:",link[0]) if __name__ == '__main__': josephus(41,3)
2.魔术师发牌问题
魔术师发牌问题的简介:一位魔术师掏出一叠扑克牌,魔术师取出其中13张黑桃,洗好后,把牌面朝下。说:“我不看牌,只数一数就能知道每张牌是什么?”魔术师口中念一,将第一张牌翻过来看正好是A;魔术师将黑桃A放到桌上,继续数手里的余牌,第二次数1,2,将第一张牌放到这叠牌的下面,将第二张牌翻开,正好是黑桃2,也把它放在桌子上。第三次数1,2,3,前面二张牌放到这叠牌的下面,取出第三张牌,正好是黑桃3,这样依次将13张牌翻出,全部都准确无误。求解:魔术师手中牌的原始顺序是什么样子的?
#魔术师发牌问题 ## 建立两个数组,类似于循环链表: ## 其中v_l数组存放要按发牌前顺序排放的数值,其初始化为任意值; ## 再建立一个l数组存放每次需要展示数值的地址,初始化为1:13;表示发牌前的排列顺序;并动态调整,如需要展示1时,则牌为1的地址为1,需要展示2的时候,则牌为2的地址为3 n = int(input("please input n:" )) v_l = [1]*n ## 初始化存储数值 l = list(range(1,n+1)) ## 初始化地址数值 i = 0 ## 标记数数的次数,初始化为0 pos = 1 ## 标记该次要展现的数值,初始化为1 ## 循环取数,没进行一次,将地址数值L进行调整,使报过的地址放置在地址数值后面;若数数到了需要展现的数值时,则将该地址去掉,并将对应地址的v_lf赋值为pos ## 在大循环上,每次循环去掉地址数值的某个数,而该数表示的地址即为v_l的地址,其值即为第pos次要展示的数值 while len(l)>=1: i = i+1 if i == pos: v_l[l[0]-1] = pos l = l[1:] pos = pos+1 i = 0 else: temp = l[:1] l.extend(temp) l = l[1:] print(str(n)+'张牌的排列顺序为' ,v_l)
3.汉诺塔
汉诺塔:汉诺塔(又称河内塔)问题是源于印度一个古老传说的益智玩具。大梵天创造世界的时候做了三根金刚石柱子,在一根柱子上从下往上按照大小顺序摞着64片黄金圆盘。大梵天命令婆罗门把圆盘从下面开始按大小顺序重新摆放在另一根柱子上。并且规定,在小圆盘上不能放大圆盘,在三根柱子之间一次只能移动一个圆盘。
def move(n,a,b,c): if n==1: print(a,'-->',c) else: move(n-1,a,c,b) #将前n-1个盘子从a移动到b上 move(1,a,b,c) #将最底下的最后一个盘子从a移动到c上 move(n-1,b,a,c) #将b上的n-1个盘子移动到c上 move(3,'A','B','C')