假设n,a,b是正整数,其中n不是素数,使得n = ab且a≥b且(a-b)尽可能小。如果给出n,找到a和b的值的最佳算法是什么?
我读了一个解决方案,他们试图通过搜索大于n的正方形S来表示n作为两个正方形之间的差异,使得S - n =(另一个正方形)。为什么这比仅仅找到n的素因子并搜索其中a,b是n和a-b的因子最小化的组合更好?
答案 0 :(得分:3)
首先....回答为什么你的方法
简单地找到n的素因子并搜索其中a,b是n和a-b因子的组合被最小化
不是最佳选择:
假设您的号码为n = 2^7 * 3^4 * 5^2 * 7 * 11 * 13 (=259459200)
,且在int
的范围内。从组合学理论来看,这个数字确实有(8 * 5 * 3 * 2 * 2 * 2 = 960)
个因子。所以,首先你找到所有这960个因子,然后找到所有对(a,b),使得a * b = n
,在这种情况下将是(6C1 + 9C2 + 11C3 + 13C4 + 14C5 + 15C6 + 16C7 + 16C8)
个方式。 (如果我没错,我的组合有点弱)。如果以最佳方式实施,则为1e5
。此外,这种方法的实施很难。
现在,为什么方差的方法
表示S-n = Q,使得S和Q是正方形
很好:
这是因为如果您可以代表S - n = Q
,则表示n = S - Q
=> n = s^2 - q^2
=> n = (s+q)(s-q)
=> Your reqd ans = 2 * q
现在,即使您迭代所有方格,您也可以找到答案,或者当2个连续方格的差异大于n
时终止
但我不认为这对所有n
都是可行的(例如,如果n=6
,则(S,Q)
没有解决方案。)
另一种方法:
从floor(sqrt(n))
迭代到1.第一个数字(例如x),x|n
将成为所需对中(a,b)
中的一个数字。其他将是,obvs,y = x/n
。所以,你的回答是y - x
。
这是O(sqrt(n))
时间复杂算法。
答案 1 :(得分:2)
一般方法可能是这样的:
找到您的数字的素数分解: n = Π p i a 我 的。除了 n 是素数或半素数的最坏情况之外,这将比迭代的 O(n 1/2 )时间快得多 down 来自平方根,它不会将找到的因子除以数字。
Recall最简单的,试验除法,素数因子分解是通过反复尝试通过增加数字的平方根以下的奇数(或素数)来划分数字,除以每个因子的数字 - 因此可以通过构造来实现 - 因为它被发现(n := n/f
)。
然后,懒惰enumerate the factors of n in order从其素数因子化。生产一半后停止。因此找到了最接近其平方根的 n (不一定是素数)因子,通过简单除法找到第二个因子。
如果必须重复多次运行,那么在预计计算 n 平方根下面所需的素数时,将大大付出代价,以便在分解中使用。