问:
【基础题】:有 n 个人围成一圈,顺序排号。从第一个人开始报数(从 1 到 3 报数) ,凡报到 3 的人退出圈子,问最后留下的是原来第几号的那位。 (n由键盘输入,比如n=100)
【提高题】:海滩上有一堆桃子,五只猴子来分。第一只猴子把这堆桃子凭据分为五份,多了一个,这只猴子把多的一个扔入海中,拿走了一份。第二只猴子把剩下的桃子又平均分成五份,又多了一个,它同样把多的一个扔入海中,拿走了一份,第三、第四、第五只猴子都是这样做的,问海滩上原来最少有多少个桃子?
方法1:
n = int(input("输入参与人数:")) steps, num_list,kill_num_list = 3, list(map(int, list(range(1, n + 1)))), [] step, num_list_bk = steps - 1, num_list[:] def ysfh(steps): global num_list, step out_number = num_list[step] kill_num_list.append(out_number) print("{} was killed!".format(out_number)) print(num_list) print(step) step = step + steps while step >= len(num_list): step -= len(num_list) num_list = list(set(num_list)-set(kill_num_list)) num_list.sort() else: if len(num_list) == 1: pass else: ysfh(steps) ysfh(steps) print("最后一个存活的是{}号".format(num_list_bk.index(num_list.pop(0))+1))
方法2:
num = int(input('请输入共多少人:')) # 将所有人放入一个数组 list_count = list(range(1, num + 1)) # 设置一个变量,用于计算报数 count = 0 while len(list_count) > 1: # 当数组中至少有2个元素时进行循环 list_count_new = list_count[:] # 把原数组拷贝到新数组中,用于限制内层循环次数 for i in range(0, len(list_count_new)): # 内层循环开始,从第一个人开始报数 count = count + 1 # 每报一次,count计数器加1 if count % 3 == 0: # 如果count能被3整除,则是报到3的人 print('第 {} 号淘汰'.format(list_count_new[i])) list_count.remove(list_count_new[i]) # 把报到3的人移除原数组,进行下一次循环 print('最后留下的是原来的第 {} 号'.format(list_count[0]))
方法3:
n = input('请输入人数') circle = list(range(1,int(n) + 1)) i = 0 count = 1 while len(circle) > 1: if count == 3: print(f'{circle[i]}出队') del(circle[i]) count = 1 i = (i + 1) % len(circle) count += 1 print(f'最后出队的是{circle[0]}')
方法4:
n = input('请输入人数') circle = list(range(1,int(n) + 1)) i = 0 count = 1 while len(circle) > 1: if count == 3: print(f'{circle[i]}出队') del(circle[i]) count = 1 i = (i + 1) % len(circle) count += 1 print(f'最后出队的是{circle[0]}')
方法5:
def circulation(peopleNumber): lic = list(range(1, peopleNumber+1)) count = 0 while len(lic) >1: lico = lic[:] print(lico) for i in range(0, len(lico)): count = count+1 if count % 3 == 0: lic.remove(lico[i]) print(lic) if __name__ == "__main__": peopleNumber = int(input('请输入有多少人:')) circulation(peopleNumber)
【提高题】:海滩上有一堆桃子,五只猴子来分。第一只猴子把这堆桃子凭据分为五份,多了一个,这只猴子把多的一个扔入海中,拿走了一份。第二只猴子把剩下的桃子又平均分成五份,又多了一个,它同样把多的一个扔入海中,拿走了一份,第三、第四、第五只猴子都是这样做的,问海滩上原来最少有多少个桃子?
方法1:
rest = 4 while True: flag = 1 sum = rest for i in range(5): if sum % 4 != 0: flag = 0 break sum = sum * 5.0 / 4 + 1 if flag == 1: break else: rest += 4 print(f'最少有{int(sum)}个')
方法2:
# 本算法从最后一个猴子进行逆向推倒 def peach(monkey=5): pea = 4 # 最后一个猴子分完剩余的桃子 while 1: num = pea for i in range(monkey): num = num + num / 4 + 1 if num % 1 != 0: # 如果分出了小数则结束内层循环 pea += 4 # 最后的桃子一定是4的整数倍 break if num % 1 == 0: # 如果是整分 则结束 break return pea, num if __name__ == '__main__': pea, num = peach() print(pea, num)
方法3:
# 输入猴子数量 monkey = int(input("Input monkey num:")) # 定义桃子总数函数 def show(n): # 循环次数 for i in range(1, monkey+1): # 下一只猴子应该带走的桃子数 t = (n - 1) / monkey # 格式化输出 print(u'%d. 桃子有%d个, 第%i只猴吃1个, 拿走%s个。' % (i, n, i, t)) # 前一只猴子带走一份桃子后剩余的桃子总数 n = (monkey-1) * t # 定义功能函数 def fun(): # 从1开始 k = 1 while True: t = k # 循环次数 for i in range(monkey-1): # 当前猴子应拿走桃子数为tc,吃拿之前总量应为 monkey * tc + 1,前一个猴子拿走桃子数为tp,则有 (monkey-1) * tp = monkey * tc + 1 t = monkey * t + 1 # 在for循环中含有break时则直接终止循环,不执行else if t % (monkey-1): break t /= (monkey-1) # 当迭代的对象迭代完并为空时,位于else的子句将执行,即找到符合条件最小整数 else: print('如果猴子%d只:' % monkey) print('桃子总数要%d个:' % (monkey * t + 1)) show(monkey * t + 1) break k += 1 if __name__ == '__main__': fun()