python24:分治法找假币

【问题描述】

有一堆共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

【样例说明】

【评分标准】

方法一:分治法(麻烦且非常非常非常非常非常非常非常非常非常没有必要)

  • 首先为每个币编号,然后将所有的币等分为两份,放在天平的两边。这样就将区分假币的问题变为区别两堆币的问题。
  • 因为假币分量较轻,因此天平较轻的一侧中一定包含假币。
  • 再将较轻的一侧中币等分为两份,重复上述做法。
  • 直到剩下两枚银币,便可用天平直接找出假币。
# 在读入的coins列表中,从下标start开始的n个硬币中查找假硬币
def findFcoin(coins, start, n):

    if (start == n):
        print("Fake coin:{}".format(start));
        return

    sum1 = 0
    sum2 = 0

    # 偶数个,用分治法
    if ((n - start + 1) % 2 == 0):
        for i in range(start, n // 2 + 1):
            sum1 = sum1 + coins[i]
        for j in range(n // 2 + 1, n + 1):
            sum2 = sum2 + coins[j]

        if sum1 == sum2:
            print("Fake coin is not found");
            return
        elif sum1 < sum2:
            findFcoin(coins, start, n // 2)  # 用前半段
        else:
            findFcoin(coins, n // 2 + 1, n)  # 用后半段
        # 反复调用,直到只剩一个元素



    # 奇数个,用遍历
    else:
        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
                                  # 遍历过程中,元素的值一直都相等,flag=0还是不变
        if flag == 1:
            print("Fake coin:{}".format(min))
        else:
            print("Fake coin is not found");
            return




coins = list(input().split(','))
coins = [int(i) for i in coins]
findFcoin(coins,0,len(coins)-1)

方法二:直接遍历(简单且通俗易懂)

        直接从第一张纸币遍历所有纸币,找到质量小的纸币就返回下标,否则返回“找不到”

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");
    return


coins = list(input().split(','))
coins = [int(i) for i in coins]
findFalseCoin(coins, 0, len(coins) - 1)

  • 4
    点赞
  • 23
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值