计算三元组的数量a * b = c

时间:2016-04-14 08:26:46

标签: algorithm data-structures

问题是计算三元组的数量

a * b = c
where a1 <= a <= a2 and b1 <= b <= b2 and c1 <= c <= c2

输入将是a1,a2,b1,b2,c1,c2

我能想到的解决方案是使用两个嵌套循环,从a1到a2迭代,第二个从b1到b2,然后将它们相乘,看看乘法值是否在c1到c2的范围内,然后递增计数

当约束非常高时如何有效地解决问题,即所有a1,a2,b1,b2,c1,c2的值都可以在0到1000000000之间。

2 个答案:

答案 0 :(得分:1)

第1部分:O(a2 - a1)复杂度的解决方案。

首先,请注意,在给定某个a的情况下,我们可以轻松地计算bb1 <= b <= b2的数量,其中c1 <= a * b <= c2也满足c1 / a <= b <= c2 / a。后一个条件等同于max(b1, c1/a) <= b <= min(b2, c2/a),因此我们需要计算满足N(a) = floor(min(b2, c2/a)) - ceil(max(b1, c1/a)) + 1的整数b的数量。

此数字为(1) - 关系N(a1) + N(a1 + 1) + ... + N(a2)

问题的解决方案是(a, b)

这比循环所有O(a2 - a1)对并检查其产品更有效,但是,对于给定的输入幅度,它可能仍然不够快 - 复杂度为a。由于问题在bO(b2 - b1)中是对称的,因此使用N(a1, a2, b1, b2, c1, c2)复杂度可能更为有利。

在以下两部分中,我将介绍一种更有效的解决方案。

第2部分:将问题简化为更简单的问题。

让我们将N(a1, a2, b1, b2, c1, c2) = N(a1, a2, b1, b2, 0, c2) - N(a1, a2, b1, b2, 0, c1 - 1)表示为我们需要计算的值。

请注意,我们可以使用:

将问题转化为c1 = 0的两个问题

N(a1, a2, b1, b2, 0, C) = N(a1, a2, 0, b2, 0, C) - N(a1, a2, 0, b1 - 1, 0, C)

我们可以更进一步,将c1 = 0的问题减少为两个问题,其中b1 = 0,c1 = 0.这可以通过以下方式完成:

N(0, A, 0, B, 0, C)

同样,我们可以将b1 = 0和c1 = 0的问题减少为a1 = 0,b1 = 0,c1 = 0的两个问题。

因此,足以解决需要计算以下形式值的更简单问题:(a, b, c)我们需要计算自然数的三元组数{{1 } {},c = a * ba <= Ab <= Bc <= C

第3部分:O(sqrt(c2))复杂度的解决方案。

下一个有用的观察结果是,自a * b = c <= C起,以下关系中至少有一个为真:a <= sqrt(C)b <= sqrt(C) - 观察(2)

在证明的第一部分(关系1)中,我们可以有效地计算(O(1)b个好a值的数量a <= sqrt(C)是固定的。使用该关系,我们可以在O(sqrt(C))中使用a > sqrt(C)有效地计算三元组的数量。

剩下要做的是用(2)计算三胞胎的数量。根据观察b <= sqrt(C),我们知道在这种情况下需要b

因此,对于{0, 1, 2, ..., sqrt(C)}中的任何a,我们必须计算好sqrt(C) < a < A值的数量,以便(1)。我们可以再次应用关系a(这次bb的角色相反 - 现在我们会a并计算好b的数量}值,受属于某个间隔的约束)。对于{0, 1, 2, ..., sqrt(C)}中的每个a,我们可以计算O(1)中良好O(sqrt(C))的数量 - 因此此案例的复杂性再次为O(sqrt(C))

使用上述结果,我们得到O(sqrt(c2))的整体复杂性。回到最初的问题,这涉及./node_modules/.bin/webpack --env.ENV development复杂性。

答案 1 :(得分:0)

使用 b = b a的fac。即如果你试过a = 2,b = 3,那么尝试a = 3,b = 2就没有意义。

此外,一旦a * b> c2,增加a或b没有任何意义。