1. 题目
五人分鱼问题:A、B、C、D、E 五人在某天夜里合伙去捕鱼,到第二天凌晨时都疲惫不堪,于是各自找地方睡觉。
日上三杆,A 第一个醒来,他将鱼分为五份,把多余的一条鱼扔掉,拿走自己的一份。
B 第二个醒来,也将鱼分为五份,把多余的一条鱼扔掉拿走自己的一份。 。
C、D、E依次醒来,也按同样的方法拿鱼。
问他们至少捕了多少条鱼?
2. 解题思路
把问题一般化,假如一共有 n个人分鱼。设原本有 x 条鱼,A拿走自己的一份后还剩
f
(
x
)
=
n
−
1
n
(
x
−
1
)
f(x)=\frac {n-1}{n}(x-1)
f(x)=nn−1(x−1)条鱼,B拿走自己的一份后还剩
f
(
f
(
x
)
)
=
f
2
(
x
)
f(f(x))=f^2(x)
f(f(x))=f2(x)条鱼……n 个人各自拿走鱼后,剩下
f
n
(
x
)
f^n(x)
fn(x) 条鱼。
其中比较重要一点的规律是总的鱼数-1,总是能被5整除。分鱼规律如下:
A:
(
x
−
1
)
/
5
(x-1)/5
(x−1)/5
B:
(
x
−
(
(
x
−
1
)
/
5
)
−
1
)
/
5
(x-((x-1)/5)-1)/5
(x−((x−1)/5)−1)/5
C:
(
x
−
(
(
x
−
1
)
/
5
)
−
(
(
x
−
(
(
x
−
1
)
/
5
)
−
1
)
/
5
)
−
1
)
/
5
(x-((x-1)/5)-((x-((x-1)/5)-1)/5)-1)/5
(x−((x−1)/5)−((x−((x−1)/5)−1)/5)−1)/5
D:
(
x
−
(
(
x
−
1
)
/
5
)
−
(
(
x
−
(
(
x
−
1
)
/
5
)
−
1
)
/
5
)
−
(
(
x
−
(
(
x
−
1
)
/
5
)
−
(
(
x
−
(
(
x
−
1
)
/
5
)
−
1
)
/
5
)
−
1
)
/
5
)
−
1
)
/
5
(x-((x-1)/5)-((x-((x-1)/5)-1)/5)-((x-((x-1)/5)-((x-((x-1)/5)-1)/5)-1)/5)-1)/5
(x−((x−1)/5)−((x−((x−1)/5)−1)/5)−((x−((x−1)/5)−((x−((x−1)/5)−1)/5)−1)/5)−1)/5
E:
(
x
−
(
(
x
−
1
)
/
5
)
−
(
(
x
−
(
(
x
−
1
)
/
5
)
−
1
)
/
5
)
−
(
(
x
−
(
(
x
−
1
)
/
5
)
−
(
(
x
−
(
(
x
−
1
)
/
5
)
−
1
)
/
5
)
−
1
)
/
5
)
−
(
(
x
−
(
(
x
−
1
)
/
5
)
−
(
(
x
−
(
(
x
−
1
)
/
5
)
−
1
)
/
5
)
−
(
(
x
−
(
(
x
−
1
)
/
5
)
−
(
(
x
−
(
(
x
−
1
)
/
5
)
−
1
)
/
5
)
−
1
)
/
5
)
−
1
)
/
5
)
−
1
)
/
5
(x-((x-1)/5)-((x-((x-1)/5)-1)/5)-((x-((x-1)/5)-((x-((x-1)/5)-1)/5)-1)/5)-((x-((x-1)/5)-((x-((x-1)/5)-1)/5)-((x-((x-1)/5)-((x-((x-1)/5)-1)/5)-1)/5)-1)/5)-1)/5
(x−((x−1)/5)−((x−((x−1)/5)−1)/5)−((x−((x−1)/5)−((x−((x−1)/5)−1)/5)−1)/5)−((x−((x−1)/5)−((x−((x−1)/5)−1)/5)−((x−((x−1)/5)−((x−((x−1)/5)−1)/5)−1)/5)−1)/5)−1)/5
3. 代码实现
def find_minimum_fish():
# 初始总鱼数为1
x = 1
# 不断尝试增加总鱼数,直到找到满足条件的值
while True:
# 每次循环重新初始化剩余鱼的数量为当前总鱼数
remaining_fish = x
# 模拟每个人的操作
for _ in range(5):
# 按照规定的方式分鱼,每次剩下4份
remaining_fish = (remaining_fish -1)*(4 / 5)
# 如果剩余鱼的数量不能被5整除,说明不符合条件,跳出内循环
if remaining_fish % 1 != 0: # 修改此行为判断是否为整数
break
else:
# 如果所有人都拿了一份鱼,返回当前的总鱼数
return int(x)
# 如果不符合条件,尝试下一个总鱼数
x += 1
# 调用函数获取结果
result = find_minimum_fish()
# 打印结果
print(f"五人至少捕了{result}条鱼。")
4. 变种问题
4.1 问题描述
有五个人捕到了一堆鱼,打算进行分配。规定如下:每个人依次取走鱼的四分之一,但最后一人不扔掉剩余的鱼。找到最小的初始鱼的数量,使得每个人都能平均分到整数条鱼。
4.2 代码实现
def find_minimum_fish_variant2():
x = 1
while True:
remaining_fish = x
for i in range(5):
remaining_fish = (3 / 4) * (remaining_fish - 1) if i < 4 else (3 / 4) * remaining_fish
if remaining_fish % 1 != 0:
break
else:
return int(x)
x += 1
result_variant2 = find_minimum_fish_variant2()
print(f"五人至少捕了{result_variant2}条鱼。")
4. 参考
https://www.runoob.com/python3/python-five-fish.html