首页 > 编程语言 >算法分析-寻找假币题

算法分析-寻找假币题

时间:2023-11-28 11:55:44浏览次数:30  
标签:硬币 list 寻找 算法 group1 假币 coin 称量

一.题目需求

你手里有70枚重量相等的真金硬币,但你知道其中有一枚是假币,比其他金币轻。
你有一个平衡秤,你可以一次在两边放上任意数量的硬币,它会告诉你两边是否重量相同,或者如果不相同,哪边更轻。
问题:请概述一个寻找假币的算法。你需要称量多少次?怎么使得称量次数最少?

二、算法思想

1.算法分析
1.1. 这个问题可以使用分治算法来解决。
1.2. 我们可以将硬币分成三组,如70枚,先分成,前两组包含23枚硬币,第三组含24枚硬币。
1.3. 然后我们使用平衡秤先称量前两组硬币,如果两边重量相同,那么假币就在剩下的第三组中。然后递归上述操作。
1.4. 如果两边重量不同,那么假币就在较轻的那一边。然后递归上述操作,直到最后只有1枚时,即可找到假币。

三、代码展示
1.天枰称量方法
输入两组硬币列表参数,比较两组总数量值,返回左右哪组轻,或相等:

def balance_scale(group1, group2):
    total1 = sum(group1)
    total2 = sum(group2)

    if total1 < total2:
        return "left"
    elif total1 > total2:
        return "right"
    else:
        return "equal"

2.寻找假币方法

1.1. 采用三分法,寻找假币。
1.2. 我们可以将硬币分成三组,如70枚,先分成,前两组包含23枚硬币,第三组含24枚硬币。
1.3. 然后我们使用平衡秤先称量前两组硬币,如果两边重量相同,那么假币就在剩下的第三组中。然后递归上述操作。
1.4. 如果两边重量不同,那么假币就在较轻的那一边。然后递归上述操作,直到最后只有1枚时,即可找到假币。

def find_fake_coin_by_three_partition(coin_list):
    '''
    @方法名称: 三分法,寻找假币方法
    @中文注释: 三分法,寻找假币方法
        我们可以将硬币分成三组,前两组包含23枚硬币,第三组含24枚硬币。
        然后我们使用平衡秤先称量前两组硬币,如果两边重量相同,那么假币就在剩下的第三组中;
        如果两边重量不同,那么假币就在较轻的那一边。依次类推即可找到假币。
    @入参:
        @param coin_list list 硬币列表
    @出参:
        @param count int 称量次数
    @作    者: PandaCode辉
    @创建时间: 2023-11-28
    @使用范例: find_fake_coin_by_three_partition([1,1,1,1,0,1,1])
    '''
    print('=====================')
    # 硬币列表最后只剩1枚时,即找到假币,结束
    if len(coin_list) == 1:
        return 1
    # 硬币列表最后只剩2枚时
    elif len(coin_list) == 2:
        print(coin_list)
        # 还剩2枚,再分2组,再称量一次
        print('还剩2枚,再分2组,再称量一次')
        group_size = 1
        group1 = coin_list[:group_size]
        group2 = coin_list[group_size:]
        result = balance_scale(group1, group2)
        return find_fake_coin_by_three_partition(group1 if result == "left" else group2) + 1
    else:
        # 将硬币列表,三等分大小
        group_size = len(coin_list) // 3
        # 前两组,硬币数量保持一致
        group1 = coin_list[:group_size]
        group2 = coin_list[group_size:2 * group_size]
        # 第三组,硬币数量,取最后剩余值
        group3 = coin_list[2 * group_size:]
        print(group1)
        print(group2)
        print(group3)
        # 天枰称量,前两组
        result = balance_scale(group1, group2)
        print(result)
        # 如果前两组重量相同,那么假币就在剩下的第三组中
        if result == "equal":
            return find_fake_coin_by_three_partition(group3) + 1
        else:
            # 如果前两组重量不同,那么假币就在较轻的那一边。
            return find_fake_coin_by_three_partition(group1 if result == "left" else group2) + 1

这个算法的时间复杂度是O(logn)。

时间复杂度分析:

这个算法使用了三分法来寻找假币。在每次递归调用中,硬币列表被分成三等分,然后进行称量。
这个过程会一直重复,直到只剩下一枚硬币为止。
因此,每一次递归调用都会将问题的规模减半,所以时间复杂度是O(logn)。这里的n是硬币列表的长度。

3.实现主函数

if __name__ == "__main__":
    # 假设有70枚真金硬币,1-为真币,其中一枚是假币,0-为假币
    coin_list = [1 for i in range(70)]
    # 随机选择一个索引,随机选择其中一枚设为假币
    random_index = random.randint(0, len(coin_list) - 1)
    # 修改选中的元素,0-为假币
    coin_list[random_index] = 0
    print(coin_list)
    print("需要称{}次,找到假币。".format(find_fake_coin_by_three_partition(coin_list)))

4.运行结果

从运行结果可以看出,只需称量5次,就能找到假币。

==========结束==========

 

标签:硬币,list,寻找,算法,group1,假币,coin,称量
From: https://www.cnblogs.com/xh2023/p/17861574.html

相关文章

  • 文心一言 VS 讯飞星火 VS chatgpt (145)-- 算法导论12.1 5题
    五、用go语言,因为在基于比较的排序模型中,完成n个元素的排序,其最坏情况下需要Ω(nlgn)时间。试证明:任何基于比较的算法从n个元素的任意序列中构造一棵二又搜索树,其最坏情况下需要Ω(nlgn)的时间。我个人喜欢灵小智。文心一言:首先,我们要明白二叉搜索树(BST)的性质:每个节点......
  • 差分算法总结
    差分是前缀和的逆运算一维差分对于a1,a2,…,an,构造b1,b2,…,bn,使得ai= b1+ b2 + …+bi。此时,b数组成为a数组的差分,a数组称为b数组的前缀和。题目链接:https://www.acwing.com/problem/content/799/代码模版:1#include<iostream>23usingnamespacestd;45co......
  • O(nlogn)排序算法
    排序算法介绍常见时间复杂度为\(O(nlogn)\)的排序算法1.快速排序分治思想#include<bits/stdc++.h>usingnamespacestd;constintN=1e5+10;inta[N];voidquick_sort(intl,intr){if(l>=r)return;intx=a[l+r>>1],i=l-1,j=r+1;......
  • DFS算法的非递归遍历分析
    两种写法,一个是边表顶点号全部压栈,一个是类似后序非递归遍历1、voidDFS(GraphG,inti){intp,w;StackS;InitStack(S);Push(S,i);visited[i]=true;while(!isEmpty(S)){Pop(S,p);printf("%d",G.Ver[p].num);......
  • 基于图像形态学处理和边缘提取算法的路面裂痕检测matlab仿真
    1.算法运行效果图预览   2.算法运行软件版本matlab2022a 3.算法理论概述       路面裂痕检测是基于图像处理和机器视觉的一种重要应用。通过图像形态学处理和边缘提取算法,我们可以有效地检测出路面的裂痕。路面裂痕检测主要基于图像处理和机器视觉的原理。......
  • 基于深度学习网络的烟雾检测算法matlab仿真
    1.算法运行效果图预览  2.算法运行软件版本matlab2022a 3.算法理论概述      基于深度学习网络的烟雾检测算法是一种端到端的检测方法,主要分为基于候选区域的二阶段目标检测器和基于回归的单阶段目标检测器两类。      基于候选区域的二阶段目标检测......
  • 前缀和算法总结
    前缀和思维导图:一维前缀和算法模版:1#include<iostream>23usingnamespacestd;45constintN=100010;67intn,m;8ints[N];910intmain()11{12scanf("%d%d",&n,&m);13for(inti=1;i<=n;i++)14......
  • 排序算法之冒泡排序优化1
    一:概述原始的数列{4,8,6,3,9,2,1,7},执行至第6步和第7步时,数列状态如下:很明显的可以看出,经过第6轮排序之后,整个数列已然是有序的了。可是排序算法依然是继续执行第7轮排序。在这种情况下,如果能判断出数列已经有序,并作出标记,那么剩下的几轮就不必执行了,可以提前结束。二:具体代码优化的......
  • 最小生成树(Kruskal和Prim算法)
    最小生成树(Kruskal和Prim算法)部分资料来源于:最小生成树(Kruskal算法)_kruskal算法求最小生成树-CSDN博客、【算法】最小生成树——Prim和Kruskal算法-CSDN博客关于图的几个概念定义:连通图:在无向图中,若任意两个顶点vi与vj都有路径相通,则称该无向图为连通图。强连通图:在有向图中,若......
  • Proj4:改进LiteOS中物理内存分配算法
    Proj4:改进LiteOS中物理内存分配算法实验目的掌握LiteOS系统调用的自定义方法实验环境Ubantu和IMX6ULLmini实验内容(从代码角度详细描述实验的步骤和过程)原先代码:1/*23*Description:findsuitablefreeblockuse"bestfit"algorithm45*Input......