三分法找假币

 问题:

 有n个硬币,其中有⼀枚是假币,假币⽐真币要轻,现有⼀天平,通过⽐较找出假币。

三分法思路:
1.将硬币分为三堆,每堆按照n/3向上取整个硬币来分配(主要分配前两堆,第三堆就是剩下的)
2.⽐较第⼀堆和第⼆堆硬币重量
若重量相等,则在第三堆中找假币,重复第⼀步
若第⼀堆⽐第⼆堆重,则在假币在第⼆堆中,去第⼆堆中找假币,重复第⼀步
若第⼆堆⽐第⼀堆重,则在假币在第⼀堆中,去第⼀堆中找假币,重复第⼀步
三分递归解法:

    def findFalseCoin(coins, idxStart, iLength):
        if iLength == 1:
            return idxStart

        n = ceil(iLength / 3)
        wPart1 = sum(coins[idxStart:idxStart + n])
        wPart2 = sum(coins[idxStart + n:idxStart + 2 * n])
        wPart3 = sum(coins[idxStart + 2 * n:iLength])
        if wPart1 < wPart2:
            return findFalseCoin(coins, idxStart, n)
        elif wPart1 > wPart2:
            return findFalseCoin(coins, idxStart + n, n)
        else:
            return findFalseCoin(coins, idxStart + 2 * n, iLength-2*n)


    if __name__ == '__main__':
        coins = [100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100]

        for i in range(len(coins)):
            coinsCopy = coins[:]
            coinsCopy[i] = 99
            r = findFalseCoin(coinsCopy,0,len(coinsCopy))
            print(f'False coin idx:{r}, weight:{coinsCopy[r]}')

三分非递归解法:

def findFalseCoin(coins):
    # 查找范围:从idxStart下标开始的iLength个硬币
    idxStart, iLength = 0 , len(coins)

    while True:
        if iLength == 1:
            return idxStart

        n = ceil(iLength / 3)
        wPart1 = sum(coins[idxStart:idxStart + n])
        wPart2 = sum(coins[idxStart + n : idxStart + 2 * n])
        wPart3 = sum(coins[idxStart + 2 * n : iLength])
        if wPart1 < wPart2:
            idxStart, iLength = idxStart, n
        elif wPart1 > wPart2:#在第二堆
            idxStart, iLength = idxStart + n , n
        else:
            idxStart, iLength = idxStart + 2 * n , iLength - 2 * n


if __name__ == '__main__':
    coins = [100] * 11

    for i in range(len(coins)):
        coinsCopy = coins[:]
        coinsCopy[i] = 99
        r = findFalseCoin(coinsCopy)
        print(f'False coin idx:{r}, weight:{coinsCopy[r]}')

  • 0
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
三分法是一种数值计算方法,用于求解一元函数的极值或者方程的根。对于假币问题,可以使用三分法来判断一个硬币是否为真币。 以下是一个基于三分法假币检测的 C 语言程序示例: ```c #include <stdio.h> // 模拟硬币重量函数 double Weight(int n) { if (n <= 0) return 0; if (n == 1) return 1.0; if (n % 2 == 0) return Weight(n / 2) + Weight(n / 2); else return Weight(n / 2) + Weight(n / 2 + 1); } // 三分法求解假币问题 int FindFakeCoin(int left, int right) { int mid1, mid2; double w1, w2, w3; while (left < right) { mid1 = left + (right - left) / 3; mid2 = right - (right - left) / 3; w1 = Weight(left); w2 = Weight(mid1); w3 = Weight(mid2); if (w1 == w2 && w2 == w3) return -1; // 三个硬币重量相等,无法判断 else if (w1 < w2 && w2 < w3) left = mid1 + 1; // 假币在 mid2 的右边 else if (w1 > w2 && w2 > w3) right = mid2 - 1; // 假币在 mid1 的左边 else { left = mid1 + 1; right = mid2 - 1; } // 假币在 mid1 和 mid2 之间 } return left; } int main() { int n; printf("请输入硬币数量:"); scanf("%d", &n); int fake = FindFakeCoin(1, n); if (fake == -1) printf("无法判断硬币真假!\n"); else printf("第 %d 枚硬币假币!\n", fake); return 0; } ``` 在程序中,我们定义了一个模拟硬币重量的函数 `Weight(int n)`,用于计算第 n 枚硬币的重量。对于假币问题,我们可以假设真币和假币的重量相差 1,然后使用递归的方式模拟硬币的重量。 在 `FindFakeCoin(int left, int right)` 函数中,我们使用三分法硬币进行判断。首先,我们将硬币分成三个部分,分别为 `left` 到 `mid1`、`mid1` 到 `mid2`、`mid2` 到 `right`。然后,我们分别计算这三个部分的重量,并进行比较。如果三个部分的重量相等,说明无法判断,返回 -1;如果重量递增,说明假币在 `mid2` 的右边;如果重量递减,说明假币在 `mid1` 的左边;否则,假币在 `mid1` 和 `mid2` 之间。最后,我们将 `left` 和 `right` 更新到新的位置,并继续进行判断,直到 `left` 和 `right` 相等。 在 `main()` 函数中,我们输入硬币的数量,然后调用 `FindFakeCoin()` 函数进行判断。如果返回值为 -1,说明无法判断;否则,返回的值就是假币的位置。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值