问:
[基础题] : 有 n 个人围成一圈, 顺序排号. 从第一个人开始报数(从 1 到 3 报数) , 凡报到 3 的人退出圈子, 问最后留下的是原来第几号的那位. (n 由键盘输入, 比如 n=100)
[提高题] : 海滩上有一堆桃子, 五只猴子来分. 第一只猴子把这堆桃子凭据分为五份, 多了一个, 这只猴子把多的一个扔入海中, 拿走了一份. 第二只猴子把剩下的桃子又平均分成五份, 又多了一个, 它同样把多的一个扔入海中, 拿走了一份, 第三, 第四, 第五只猴子都是这样做的, 问海滩上原来最少有多少个桃子?
答:
[基础题] : 有 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()
来源: http://www.bubuko.com/infodetail-3074174.html