如何在没有强制执行的情况下进行Euler 5?

时间:2015-02-09 15:54:29

标签: java algorithm brute-force

在我目前的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++;
      }
  }
}

2 个答案:

答案 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相当容易。