天平与假币问题

天平与假币

假设现在有12枚硬币,已知其中有一枚是假币,但是不知道这枚假币是重还是轻;假如现在给你一架没有砝码的天平,那么你至少需要称量多少次才能找出这枚假硬币。。

问题分析

随机将12枚硬币等分成3组,每组4个,分别标记为A,B,C;

取A和B,分别放在天平的两端(A放左边,B放右边),称重,有以下三种结果:

1)如果天平平衡,表明A和B中都没有假币,

2)A比B重;

3)A比B轻;

明显,第二种和第三种情况可以合并成一种来进行分析;

天平平衡的情况

天平平衡,说明A和B中都没有假币,假币一定在C组中,将C组的四枚硬币分别编号为1,2,3,4;

取出硬币1和2放于天平上称量,如果平衡,说明硬币1和2都是真的,那么硬币3和4中一定有假币;

取出1和3称重,如果天平不平衡,说明3就是假币;

如果天平平衡,说明3也是真的,那么4就是假币;

A比B重的情况

A比B重,说明假币肯定在A和B中,C中的都是真硬币;于是将A中的四个硬币分别编号为5,6,7,8,B中的分别编号为9,10,11,12,而C中的分别1,2,3,4,即:

5678 > 9101112    公式一

取出硬币5,6和9放在天平的左端,硬币7,8和1放在天平的右端,称重,同样有三种情况:

1)天平平衡:说明假币在B组的6,7和8中,且假币轻;

2)左端比右端重:说明5和6中有假币,且假币重;因为在公式一的条件保证下,不可能9是假币;也不可能是7和8;

3)左端比右端轻:说明a)3和4有假币,且假币重;b)5是假币,且假币轻;

针对上面的几种情况,都至多需要再称重一次就可以找到假币是谁;

理论验证

对于每一次的天平称重,都存在三种情况:平衡、左边重,右边重;

如果把每一次称重当做一位编码,那么该编码就是三进制的,这时问题就转化为,12枚硬币需要多少位才够编码呢?

因为假币的轻重未知,所以有两种可能,因此12变成24,那么用三进制来表示24,需要多少位呢?

设需要n位,则3的n次方≥24,解得:n≥2.89,因此至少需要3刺称重才能找到假币。



  • 2
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 4
    评论
以下是两种假币问题的Python代码: 方法一:直接遍历所有纸币,找到质量小的纸币就返回下标,否则返回“找不到” ```python def findFalseCoin(coins, start, n): min = coins[start] flag = 0 for i in range(start, n + 1): if coins[i] < min: flag = 1 min = i break elif coins[i] > min: flag = 1 min = start break if flag == 1: print("Fake coin:{}".format(min)) else: print("Fake coin is not found") coins = list(input().split(',')) coins = [int(i) for i in coins] findFalseCoin(coins, 0, len(coins) - 1) ``` 方法二:将两堆硬币上天平比较重量,如果有一堆较轻,那么假的硬币必然在轻的那一堆中。如果两堆硬币重量相等,且两堆之外有一个剩余硬币,则那个剩余硬币就是假硬币。如果两堆硬币重量相等,且两堆之外没有剩余硬币,则查找任务失败,未发现假硬币。 ```python def findFalseCoin(coins): n = len(coins) if n % 2 == 0: left = coins[:n//2] right = coins[n//2:] left_sum = sum(left) right_sum = sum(right) if left_sum < right_sum: return findFalseCoin(left) elif left_sum > right_sum: return findFalseCoin(right) else: return -1 else: left = coins[:n//2] right = coins[n//2+1:] left_sum = sum(left) right_sum = sum(right) if left_sum < right_sum: return findFalseCoin(left) elif left_sum > right_sum: return findFalseCoin(right) else: return coins[n//2] coins = list(input().split(',')) coins = [int(i) for i in coins] result = findFalseCoin(coins) if result == -1: print("Fake coin is not found") else: print("Fake coin:{}".format(result)) ```

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值