在我目前的Project Euler problem 5中,我有一个"工作"解。它适用于较小的数字(问题中的示例),但不适用于实际问题,因为我强行执行,程序无法完成。
以下是问题的解释:
2520是可以除以1到10之间的每个数字的最小数字,没有任何余数。
从1到20的所有数字可分割 1 的最小正数是多少?
1 :可分割,没有余数
这是我目前的代码:
package Euler;
public class Euler5 {
public static void main(String[] args) {
int desiredNumber = 20;
boolean exitLoop = false;
long counter = 1;
while(exitLoop == false) {
long loopCounter = 0;
for(int i=1; i<=desiredNumber; i++) {
if(counter % i == 0) {
loopCounter++;
}
}
if(loopCounter == desiredNumber) {
exitLoop = true;
System.out.println(counter);
}
counter++;
}
}
}
答案 0 :(得分:3)
你没有电脑来回答这个问题。看:如果一个数字可以除以1到20之间的每个数字,这意味着它应该是相应权力中素数的乘法:
2**4 (from 16)
3**2 (from 9)
5
7
11
13
17
19
所以解决方案是
16 * 9 * 5 * 7 * 11 * 13 * 17 * 19 == 232792560
因为答案非常大我怀疑暴力是否是合理的方法。
在 一般情况 (对于某些n >= 2
)中找出所有未执行n的素数 <: / p>
2, 3, ..., m (m <= n)
然后,对于每个素数a
,找出幂pa
,使
a**pa <= n
但是
a**(pa + 1) > n
答案将是
2**p2 * 3**p3 * ... * m**pm
可能的Java实现:
public static BigInteger evenlyDivisible(int n) {
if (n <= 0)
throw new IllegalArgumentException("n must be positive");
else if (n <= 2)
return BigInteger.valueOf(n);
ArrayList<Integer> primes = new ArrayList<Integer>();
primes.add(2);
for (int i = 3; i <= n; i += 2) {
boolean isPrime = true;
for (int p : primes) {
if (i % p == 0) {
isPrime = false;
break;
}
else if (p * p > i)
break;
}
if (isPrime)
primes.add(i);
}
BigInteger result = BigInteger.ONE;
for(int p : primes) {
// Simplest implemenation, check for round up errors however
int power = (int)(Math.log(n) / Math.log(p));
result = result.multiply(BigInteger.valueOf(p).pow(power));
}
return result;
}
...
System.out.println(evenlyDivisible(20)); // 232792560
答案 1 :(得分:1)
您所寻求的数字是数字1,2,3,...,20的 Least common multiple (LCM) 。
通过将每个数字拆分为其素因子的乘法(对于小数字而言很容易),找到LCM相当容易。