我正在尝试找到可被1到20之间的所有数字整除的最小正数,这是代码:
$num = 2520;
$x = 1;
while($x < 21){
if($num % $x == 0){
$x++;
}else{
$num += 20;
$x = 1;
}
}
echo $num;
它在不到1分钟的时间内提供了正确的输出。这个执行时间在专业领域是不是很糟糕?有什么办法优化这个?
P.S。我从2520开始,因为它是可以除以1到10之间的每个数字的最小数字,没有任何余数。
答案 0 :(得分:1)
建议:在[1,20]中找到所有整数的素数。
例如,我们有素数{2,3,5,7,11,13,17,19}。所以,如果解决方案是可分的 通过[1,20]中的所有整数,当然它可以被这个中的每个元素整除 素数列表。所以,至少,我们的解决方案是&gt; = 2 * 3 * 5 * 7 * 11 * 13 * 17 * 19,对吧?
现在的问题是我们如何聪明地构建候选解决方案 大于那个数字。好吧,让我们先看看有多少解决方案已经完成......
2 * 3 * 5 * 7 * 11 * 13 * 17 * 19可被4整除吗?不,所以,让我们多来2来得到 2 * 2 * 3 * 5 * 7 * 11 * 13 * 17 * 19,一定可以被2 * 2整除......
2 * 2 * 3 * 5 * 7 * 11 * 13 * 17 * 19可以被6整除吗?是。
2 * 2 * 3 * 5 * 7 * 11 * 13 * 17 * 19可被8整除吗? ....
你得到了照片。虽然我不确定,但我相信这种方法会 得到正确的答案 - 即每个可被整除的最小整数 [1,20]中的整数。
答案 1 :(得分:0)
这听起来像Project Euler's Problem 5。
我们在这里找到的是数字1到20的least common multiple。您可以在greatest common divisor的帮助下找到它:
function gcd($a, $b) {
if ($a == 0) return $b;
return gcd($b % $a, $a);
}
function lcm($a, $b) {
return $a * $b / gcd($a, $b);
}
function smallestDiv($n) {
$div = 1;
for ($i = 1; $i <= $n; $i++) {
$div = lcm($div, $i);
}
return $div;
}
echo smallestDiv(20);
原谅我的PHP。自从我写完以来已经有一段时间了。
请注意,我们也可以通过每个数字的素数分解找到答案,并查找here和Kode Charlie's中所述的最大指数:
2 = 2
3 = 3
4 = 2²
5 = 5
6 = 2 × 3
7 = 7
8 = 2³
9 = 3²
10 = 2 × 5
11 = 11
12 = 2² × 3
13 = 13
14 = 2 × 7
15 = 3 × 5
16 = 2⁴
17 = 17
18 = 2 × 3²
19 = 19
20 = 2² × 5
lcm(1,2,…20) = 2⁴ × 3² × 5 × 7 × 11 × 13 × 17 × 19 = 232,792,560
答案 2 :(得分:0)
使用改良的Eratosthenes筛子进行大规模加速
1.int ix [20] = {1,2,3,4,... 20};
2.现在写一个循环
3.如果没有那么增量也是ix [19] + = 20;
[注释]