Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/algorithm/11.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Algorithm 利用阵列模拟假硬币_Algorithm_Recursion - Fatal编程技术网

Algorithm 利用阵列模拟假硬币

Algorithm 利用阵列模拟假硬币,algorithm,recursion,Algorithm,Recursion,有70枚硬币,其中有一枚是假的。需要在最少数量的称重中检测假硬币。你只有一个秤,你知道假硬币更轻 我不确定下面对问题的模拟是对是错,即在数组中表示它,并像我在代码中所做的那样进行比较。我试着用一个数组来模拟它,除了一个被认为是假的零之外,其他的都是一个。下面是我的代码。如果我弄错了,请告诉我 如果有人能证明/解释为什么三元除法在简单数学中更好,那将非常有帮助 以下代码的伪代码: INPUT : integer n if n = 1 then the coin is fake els

有70枚硬币,其中有一枚是假的。需要在最少数量的称重中检测假硬币。你只有一个秤,你知道假硬币更轻

我不确定下面对问题的模拟是对是错,即在数组中表示它,并像我在代码中所做的那样进行比较。我试着用一个数组来模拟它,除了一个被认为是假的零之外,其他的都是一个。下面是我的代码。如果我弄错了,请告诉我

如果有人能证明/解释为什么三元除法在简单数学中更好,那将非常有帮助

以下代码的伪代码:

INPUT    : integer n

if n = 1 then
   the coin is fake
else
   divide the coins into piles of A = ceiling(n/3), B = ceiling(n/3),
       and C = n-2*ceiling(n/3)
   weigh A and B
   if the scale balances then
      iterate with C
   else
      iterate with the lighter of A and B
代码:

随机导入
def getmin(数据、开始、结束、总项目):
如果项目总数=1:
#当然我们有一枚假硬币
返回(0,开始)
elif项目总数==2:
如果数据[开始]>数据[结束]:
返回(1,结束)
elif数据[开始]<数据[结束]:
返回(1,开始)
其他:
分区=项目总数/3
a_weight=sum(数据[开始:开始+分区])
b_权重=总和(数据[开始+分区:开始+2*分区])
c_权重=总和(数据[开始+2*分区:结束])
如果a_权重==b_权重:
结果=getmin(数据,开始+2*分区,结束,结束-(开始+2*分区))
返回(1+结果[0],结果[1])
其他:
如果a_重量>b_重量:
结果=getmin(数据,开始+分区,开始+2*分区,分区)
返回(1+结果[0],结果[1])
其他:
结果=getmin(数据、开始、开始+分区、分区)
返回(1+结果[0],结果[1])
n=int(原始输入()
数据=[1]*n
数据[random.randint(0,n-1)]=0
总称重,位置=getmin(数据,0,len(数据),len(数据))
打印(总重量、位置)

此算法的复杂性为O(log3N),因为在每次迭代中,您将问题大小减少到1/3。复杂度方面的O(log3(n))==O(log2(n))==O(log10(n)),因此,将问题大小除以3还是除以10并不重要。唯一更好的复杂性是O(1),这意味着无论问题的大小,都可以在固定数量的操作中找到伪硬币,这是不太可能的


请注意,在该算法中,我们假设我们可以在O(1)中找到一系列元素的总和,否则该算法的复杂度为O(n)。

该算法的复杂度为O(log3N),因为您在每次迭代中将问题大小减少到1/3。复杂度方面的O(log3(n))==O(log2(n))==O(log10(n)),因此,将问题大小除以3还是除以10并不重要。唯一更好的复杂性是O(1),这意味着无论问题的大小,都可以在固定数量的操作中找到伪硬币,这是不太可能的

请注意,在该算法中,我们假设可以在O(1)中找到一系列元素的和,否则该算法的复杂度为O(n)。

您会问“为什么三元除法在简单数学中更好。”比什么更好?在这个问题中,它是最好的解决方案,因为它以最少的权重获得答案。平凡天平的特性产生三个基本结果:左重、右重和等重。这是一个三方决策,因此信息论得出的结论是,最好的算法是在每个阶段将对象分成三个部分(如果你实际上可以做到的话)

28-81枚硬币需要4磅重


幸运的是,您的问题允许进行详尽的测试。 上面的代码执行一次随机测试。对于初学者来说,这没关系,但由于只需要检查70个案例,我建议您全部尝试。将主程序在范围(70)上循环,如下所示:

n = 70
for bad_coin in range(70):
    data = [1]*n
    data[bad_coin] = 0
    total_weighing, position = getmin(data, 0, n, n)
    print ("trial", bad_coin)
    if total_weighing != 4:
        print ("Wrong number of weighings:", total_weighing)
    if position != bad_coin:
        print ("Wrong ID:", position)
这将很快显示指定70个硬币的程序中的任何错误

顺便说一句,如果您对该功能感到满意,请将if语句替换为assert

您会问“为什么三元除法在简单数学中更好。”比什么更好?在这个问题中,它是最好的解决方案,因为它以最少的权重获得答案。平凡天平的特性产生三个基本结果:左重、右重和等重。这是一个三方决策,因此信息论得出的结论是,最好的算法是在每个阶段将对象分成三个部分(如果你实际上可以做到的话)

28-81枚硬币需要4磅重


幸运的是,您的问题允许进行详尽的测试。 上面的代码执行一次随机测试。对于初学者来说,这没关系,但由于只需要检查70个案例,我建议您全部尝试。将主程序在范围(70)上循环,如下所示:

n = 70
for bad_coin in range(70):
    data = [1]*n
    data[bad_coin] = 0
    total_weighing, position = getmin(data, 0, n, n)
    print ("trial", bad_coin)
    if total_weighing != 4:
        print ("Wrong number of weighings:", total_weighing)
    if position != bad_coin:
        print ("Wrong ID:", position)
这将很快显示指定70个硬币的程序中的任何错误


顺便说一句,如果您对该功能感到满意,请将if语句替换为assert

您刚才谈到了复杂性,但是如何用数组和代码模拟它呢?你认为我做对了吗?看起来不错。但为了确保这一点,您需要针对许多不同的测试对其进行测试。一个小错误——并不是说“唯一更好的复杂性是O(1)”,请参阅反例。您刚才谈到了复杂性,但如何用数组和代码模拟它呢?你认为我做对了吗?看起来不错。但是为了确定你需要用很多不同的测试来测试它。一个小错误——并不是说“唯一更好的复杂性是O(1)”,请参阅一个反例。如果你还没有确定你是否有问题,你不应该发布。为您测试程序不在SO的范围内。简单代码审查属于代码审查网站。@Prune我不想检查我的程序。我正在检查我的阵列模拟是否是解决假硬币问题的正确方法。代码只提供给illustrat