最快的方法是什么?
我的简单方法:
for (C = 1;C<sqrt(A);C++) {
B=A/(C*(C+1));
if B is natural then add B,C to the list of possible pairs.
}
可以在低于O(sqrt(A))的情况下完成吗?
解决方案
正如Egor Skriptunoff所说,可以在O(cube_root(A))中轻松完成。
这是一个简单的javascript实现。
function findBCs(A) {
if (A / 2 != Math.floor(A / 2)) return [];
var solution = [];
var i;
var SR3 = Math.pow(A, 1 / 3);
for (i = 1; i <= SR3; i++) {
var B, C;
C = i;
B = A / (C * (C + 1));
if (B == Math.floor(B)) {
solution.push([B, C]);
}
B = i;
C = (-1 + Math.sqrt(1 + 4 * A / B)) / 2;
if (C == Math.floor(C)) {
solution.push([B, C]);
}
}
return solution;
}
我接受Meh的答案,因为它应该更好(除了它的实现有点复杂,我还没有测试过。)
答案 0 :(得分:4)
可以在O(cube_root(A))
中完成
实际上,您的某个号码B
和C
必须小于cube_root(A)
答案 1 :(得分:4)
第1步:因素A
步骤2:从A的素数因子中找出所有除数的集合S.
步骤3:对于S中的每个除数c,检查c + 1是否也将A除。如果确实那么b = A /(c *(c + 1))是一个解决方案。 (这使用c和c + 1是互质的。因此,如果c和c + 1除以A,那么c *(c + 1)也是如此。
这种复杂性取决于用于因子AEg的方法,如果你实现例如Pollard-rho(相对简单)那么在最坏的情况下,实现的复杂性大约为O(A ^ 0.25) 。这仍然不是最好的答案。当然有更好的分解算法。此外,如果您的输入是一个具有大量除数的特殊情况,那么因子分解可能很容易,除数的数量也是限制问题。
这种方法的优势当然是你会花时间在一个通常有用的功能(即分解)上,这将简化解决其他类似问题。我自己在Python中实现的Pollard-rho需要总共0.03秒来处理20个示例,其中15个数字由6502发布,这已经至少是1000倍的加速。更复杂的实现应该会带来更大的改进。
为了进行比较,Egor Skriptunoff提出的O(A ^(1/3))方法的快速而肮脏的Python实现需要相同列表的0.7s。对于易于实现的方法,这当然是一个很好的结果。
答案 2 :(得分:-1)
这个python似乎有效:
from __future__ import division
from math import sqrt
def bcc1(a):
ans = []
if a % 2: return ans # for odd a
for b in range(1, a // 2 + 1):
c = max(1, int(sqrt(a / b)))
if b*c*(c+1) == a:
ans.append((b,c))
return ans
for a in range(2, 51, 2):
print('a: %2i -> (b, c): %r' % (a, bcc1(a)))
产生的输出是:
a: 2 -> (b, c): [(1, 1)]
a: 4 -> (b, c): [(2, 1)]
a: 6 -> (b, c): [(1, 2), (3, 1)]
a: 8 -> (b, c): [(4, 1)]
a: 10 -> (b, c): [(5, 1)]
a: 12 -> (b, c): [(1, 3), (2, 2), (6, 1)]
a: 14 -> (b, c): [(7, 1)]
a: 16 -> (b, c): [(8, 1)]
a: 18 -> (b, c): [(3, 2), (9, 1)]
a: 20 -> (b, c): [(1, 4), (10, 1)]
a: 22 -> (b, c): [(11, 1)]
a: 24 -> (b, c): [(2, 3), (4, 2), (12, 1)]
a: 26 -> (b, c): [(13, 1)]
a: 28 -> (b, c): [(14, 1)]
a: 30 -> (b, c): [(1, 5), (5, 2), (15, 1)]
a: 32 -> (b, c): [(16, 1)]
a: 34 -> (b, c): [(17, 1)]
a: 36 -> (b, c): [(3, 3), (6, 2), (18, 1)]
a: 38 -> (b, c): [(19, 1)]
a: 40 -> (b, c): [(2, 4), (20, 1)]
a: 42 -> (b, c): [(1, 6), (7, 2), (21, 1)]
a: 44 -> (b, c): [(22, 1)]
a: 46 -> (b, c): [(23, 1)]
a: 48 -> (b, c): [(4, 3), (8, 2), (24, 1)]
a: 50 -> (b, c): [(25, 1)]