如果有一些给定的素数:2,3,5,7 是否有一种有效的方法可以找出大于某个给定数字的最小复合数,除了允许的素数之外,它没有任何素数因子。
例如:
给定素数集:2, 3, 5, 7
如果我们想要找到一个必须大于或等于85
的复合数,并且除了2,3,5或7之外没有素数因子,答案应该是90.
因为
85 = 5 * 17 (wrong)
86 = 2 * 43 (wrong)
87 = 3 * 29 (wrong)
88 = (2 ^ 3) * 11 (wrong)
89 = 89 (wrong)
90 = 2 * (3 ^ 2) * 5 (correct)
答案 0 :(得分:1)
从起始编号开始。
使用trival除法计算当前数字。
如果当前的数字是复合数并且所有因子都在给定列表中,请停止,当前数字就是答案。
在当前号码中添加一个。
转到第2步。
答案 1 :(得分:1)
对于你的小数字的例子,蛮力方法可能没问题:测试85以上的所有数字。您不需要确定所有因素。通过连续划分列表中的素数,您可以查看是否可以将数字n
降为1。
或者,您可以使用自下而上的方法:有效的合成数字是:
2^a2 * 3^a3 * 5^a5 * 7^a7
您现在可以递归探测所有集{a2, a3, a5, a7}
。从{0, 0, 0, 0}
开始,产生1,设置索引为0.然后通过递增当前设置索引处的指数并通过增加设置索引进行探测,如果这并不意味着你超越了列表的边界。
当您遇到等于或高于阈值的数字时,请不要进一步递减。
在伪代码中:
function spread(p[], ix, num, lim)
{
if (num >= lim) {
return min;
} else {
m1 = spread(p, ix, k * p[ix], lim, min);
ix++;
if (ix == p.length) return m1
m2 = spread(p, n, ix, num, lim, min);
return min(m1, m2);
}
}
min = spread([2, 3, 5, 7], 0, 1, 85)
这种方法在你的例子中不会给你带来太大的影响,但对于较大的素数和案例来说应该更好,其中最小值不接近阈值。
答案 2 :(得分:0)
您正在找到最小数字2 ^ i 3 ^ j 5 ^ k 7 ^ l,它大于或等于某些N.
我们可以按顺序处理这些数字,直到我们得到一个大于N的数字。
最小数字是1,对应于(i,j,k,l)=(0,0,0,0)。 我们现在将这个元组推到最小堆H并添加到集合S中 (例如,使用哈希表实现)。
我们现在重复以下内容,直到找到大于N的数字:
这确保我们以正确的顺序考虑数字,因为每次删除数字/元组时,我们都会将所有新的候选者添加到堆中。
这是python中的一个实现:
import heapq
N = 85
S = set([(0,0,0,0)])
H = [( 1 , (0,0,0,0) )]
while True:
val,(i,j,k,l) = heapq.heappop(H)
if val >= N:
break
if (i+1,j,k,l) not in S:
S.add((i+1,j,k,l))
heapq.heappush(H,( val*2 , (i+1,j,k,l) ) )
if (i,j+1,k,l) not in S:
S.add((i,j+1,k,l))
heapq.heappush(H,( val*3 , (i,j+1,k,l) ) )
if (i,j,k+1,l) not in S:
S.add((i,j,k+1,l))
heapq.heappush(H,( val*5 , (i,j,k+1,l) ) )
if (i,j,k,l+1) not in S:
S.add((i,j,k,l+1))
heapq.heappush(H,( val*7 , (i,j,k,l+1) ) )
print val # 90
由于序列的大小呈指数级增长,因此迭代次数不会超过O(log N)。在每次迭代中,我们最多向H和S添加3个项,因此堆永远不会包含多于O(3 log N)个项。因此,每个堆/集操作的成本不会超过O(log log N),从而确保整个时间复杂度为O(log N * log log N)。