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