脑力题目(挑战你的逻辑思维:一个有趣的脑力题目)
脑力题目:三个强盗分金子
有三个强盗偷到了一堆金子,他们决定平分这些金子,但是数量不够平分,所以他们开始争执起来。结果一个机智的旁观者提出了一个解决办法:用他自己的金币补齐,然后平分即可。但是这个旁观者希望保留一些金子作为报酬,所以他提出了一个方案:先把金子分成三份,然后让强盗们每个人取出想要的金子,然后剩下的金子再分成三份,重复这个过程直到所有金子都平分为止。但是,旁观者只希望留下最少的金币,应该怎么办呢?
分析
假设一开始有n个金币,旁观者取出x个金币,那么强盗拿到的金币就是(n-x)/3个,剩下的金币就是(n-x)-(n-x)/3=2(n-x)/3个。所以这个问题可以用一个递归的函数来解决:用f(n, x)表示一开始有n个金币,旁观者取出x个金币时保留最小的金币数,那么f(n, x)的值可以通过以下方式计算出来:
1. 如果强盗能够平分n-x个金币,则旁观者保留x个金币;
2. 否则,将n-x个金币分成三份,让强盗取走一份,剩下的金币数为2(n-x)/3个,旁观者再取出y个金币,进入f(2(n-x)/3
, y)求解。则旁观者保留的金币数为x+y。代码实现
根据上述思路,可以编写如下的递归函数:
```python
def f(n, x):
if (n-x) % 2 == 0 and (n-x) % 3 == 0:
return x
else:
p = (n-x) // 3
y = 1
while f(2 * (n-x) // 3, y) > f(2 * (n-x) // 3 + p, y+p):
y += 1
return x + y
```
函数中用到了一个while循环,用于找到旁观者所取的金币数y,使得旁观者保留最少的金币数。具体地,假设旁观者取出y个金币,则剩下的金币应该分成3份为(2(n-x)-3y)/3,每份分别为(2(n-x)-3y)/9个金币。如果强盗们每个人分到(2(n-x)-3y)/9个金币,则旁观者保留x+y个金币即可;否则,每个强盗最多多拿((2(n-x)-3y) mod 3)/2个金币,那么旁观者所保留的金币就是x+y+p,其中p为能够使最大的强盗拿到(2(n-x)-3y)/9个金币的金币数。
测试
用上述函数可以求出解决方案,比如当n=23时,旁观者保留2个金币即可:
```python
>>> f(23, 2)
2
```
其他一些测试结果的验证见下表:
| n | x | f(n, x) |
| --- | --- | --- |
| 1 | 1 | 1 |
| 3 | 1 | 1 |
| 3 | 2 | 2 |
| 7 | 1 | 1 |
| 7 | 2 | 3 |
| 7 | 3 | 2 |
| 23 | 2 | 2 |
| 23 | 3 | 3 |
| 23 | 4 | 6 |
| 101 | 1 | 1 |
| 101 | 2 | 4 |
| 101 | 3 | 7 |
| 101 | 4 | 11 |
| 101 | 5 | 15 |
| 101 | 6 | 21 |
结论
通过递归函数的求解,可以得出一个结论:旁观者应该保留x个金币,其中x是满足强盗们每个人都能平分金币的最小整数。如果强盗们每个人都不能平分金币,则旁观者应该取出一些金币,使得最后的金币数能够平分。
发布者:脑力中国青少年专注力训练营 转载请注明出处:脑力题目(挑战你的逻辑思维:一个有趣的脑力题目)https://www.nalikepui.com/swl/9327.html