分治法找硬币

【问题描述】

有一堆共n枚硬币,其中一枚是假币,外观上无法区分,只知道假币的重量稍轻。要求仅使用一个天平,使用最少的重量比较次数找出假硬币。

n个硬币分成数量相同的两堆,如果n为偶数,每堆的硬币个数为n/2

如果n为奇数,每堆的硬币个数为(n-1)/2,两堆之外还会剩余一个硬币。

将两堆硬币上天平比较重量,如果有一堆较轻,那么假的硬币必然在轻的那一堆中。如果两堆硬币重量相等,且两堆之外有一个剩余硬币,则那个剩余硬币就是假硬币。如果两堆硬币重量相等,且两堆之外没有剩余硬币,则查找任务失败,未发现假硬币。

编写函数findFalseCoin(coins,start,n)并调用

实现"在读入的coins列表中,从下标start开始的n个硬币中查找假硬币"

【输入形式】
【输出形式】
【样例输入】

100,100,100,99,100,100,100,100,100

【样例输出】

Fake coin:3

【样例说明】

【评分标准】

代码如下:

def findFalseCoin(coins, start, n):
    if n == 1: print(f"Fake coin:{start}"); return
    group_a, group_b, group_c = group(coins)
    result = compare(group_a, group_b)
    if result == 'right': findFalseCoin(group_a, start, n // 2)
    elif result == 'left': findFalseCoin(group_b, start + n // 2, n // 2*2)
    elif result == 'equal' and len(group_c) == 0:
        print("Fake coin is not found");
    elif result == 'equal' and len(group_c) == 1:
        print(f"Fake coin:{group_c[0]}");
        
def group(coins):
    n = len(coins)
    group_a = coins[0 : n // 2]
    group_b = coins[n // 2 : n // 2 * 2]
    group_c = coins[n // 2 * 2 : n]#余数堆,最大为一
    if len(group_c) == 1: group_c[0] = n - 1
    return group_a, group_b, group_c
 
def compare(first_group, second_group):
    sum1, sum2 = sum(first_group), sum(second_group)
    if sum1 == sum2: result = 'equal'
    elif sum1 < sum2: result = 'right'
    else: result = 'left'
    return result
 
coins = list(map(int,input().split(',')))
findFalseCoin(coins,0,len(coins))

  • 1
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值