Java 投影Euler Prob 12,取2

Java 投影Euler Prob 12,取2,java,Java,我又在这里绞尽脑汁,与欧拉计划第12题搏斗。它要求第一个三角形数的除数超过500 以下是我以前的尝试: 我收到了很多很好的建议,我努力尝试去应用 感谢你们的回复,现在我可以:筛选出一个非常高的素数,对任意数进行素数分解,并计算除数 但是我不能把这些技术和寻找500个除数的三角形数的问题联系起来。所以我已经筛选出了大量的素数,那么我该怎么做呢?我对任何数字进行因式分解并计算其除数,那么如何使用它来解决这个问题呢 我回到我以前的试用解决方案并清理了代码。现在它可以找到除数低的三角形数。但是,在达到

我又在这里绞尽脑汁,与欧拉计划第12题搏斗。它要求第一个三角形数的除数超过500

以下是我以前的尝试:

我收到了很多很好的建议,我努力尝试去应用

感谢你们的回复,现在我可以:筛选出一个非常高的素数,对任意数进行素数分解,并计算除数

但是我不能把这些技术和寻找500个除数的三角形数的问题联系起来。所以我已经筛选出了大量的素数,那么我该怎么做呢?我对任何数字进行因式分解并计算其除数,那么如何使用它来解决这个问题呢

我回到我以前的试用解决方案并清理了代码。现在它可以找到除数低的三角形数。但是,在达到500的情况下,编译器会继续运行

以下是我的清理解决方案:

public static void main(String[] args) {
    long c=2;
    long d=(c*(c+1)/2);

    while (numDivs(d)<=500) {
        c++;
        d=(c*(c+1)/2);
    }
    System.out.println(d);
    System.out.println(c);

}

public static long numDivs(long a) {
    long foo=2;

    for (long b=1;b*2<=a;b++ ) {
        if (a%b==0) 
                foo++;
    }

    return foo;

}
publicstaticvoidmain(字符串[]args){
长c=2;
长d=(c*(c+1)/2);

而(numDivs(d)我认为第一件事,一个人可以做的,是以两倍的速度计算除数,只需在数的
sqrt
处剪切:

public static long numDivs(long a) {
    if(a == 1)
        return 1;
    long num = 2;
    int sqrt = (int) Math.sqrt(a);
    if(sqrt*sqrt == a) {
        num++;
    }
    for (long b = 2;b < sqrt; b++) {
        if (a%b == 0) {
                num += 2;
        }
    }
    return num;
}
公共静态长NUMDIV(长a){
如果(a==1)
返回1;
长数=2;
intsqrt=(int)Math.sqrt(a);
如果(sqrt*sqrt==a){
num++;
}
用于(长b=2;b
基本原理:如果除数大于数字的平方根,则它有一个较小的辅除数,而不是单独计算,您可以同时计算两者


这肯定会产生影响,因为
numDivs
现在的时间复杂度是O(sqrt n),而不是O(n)。

我认为您尝试应用的算法非常幼稚

检查我的代码,我认为它使用了更好的方法

寻找素数
私有静态列表筛选(int maxPrime){
boolean[]isPrime=新的boolean[maxPrime];
列表素数=新的ArrayList();
数组.fill(isPrime,true);
对于(int i=2;i*i
因式分解 这里我们得到一个映射,其中key是因子,value是它发生的次数

private static Map<Integer, Integer> factorize(List<Integer> primes, int number) {
    Map<Integer, Integer> factors = new HashMap<>();
    int tempNumber = number;
    for (Integer prime : primes) {
        while (tempNumber % prime == 0) {
            tempNumber = tempNumber / prime;
            if (factors.containsKey(prime)) factors.put(prime, factors.get(prime) + 1);
            else factors.put(prime, 1);
        }
    }
    return factors;
}
私有静态映射分解(列表素数,整数){
映射因子=新的HashMap();
int TEMPNAME=数字;
for(整数素数:素数){
while(tempNumber%prime==0){
tempNumber=tempNumber/素数;
if(factors.containsKey(prime))factors.put(prime,factors.get(prime)+1);
其他因素。put(prime,1);
}
}
回报因素;
}
计数因子
private静态int计数因子(映射因子){
int结果=1;
对于(整数c:factors.values()){
结果*=c+1;
}
返回结果;
}
行刑
publicstaticvoidmain(字符串[]args){
final int MAX_PRIME=(int)Math.sqrt(Integer.MAX_VALUE);
列表素数=筛(最大素数);
int triangularNumber=0;
对于(int i=1;i500){
打破
}
}
System.out.println(“数字”+三角形数字);
}

您不必每次都重新计算三角形数,只需添加c作为

T(n) = T(n-1) + n
所以代码明智

long c=2;
long d=(c*(c+1)/2);

while (numDivs(d)<=500) {
    c++;
    d += c;
}
长c=2;
长d=(c*(c+1)/2);

虽然(numDivs(d)这个问题似乎离题了,因为它是关于检查代码,而不是一个具体的可回答问题什么是三角形数?@CommuSoft@luigimendoza:嗯,这是一个三角形数,只是想在投资于结果不同的东西之前检查一下;)@CommuSoft euler项目中的问题链接中也解释了这一点:)谢谢。“num”的用途是什么?@bircadian:
num
是除数,在答案中修复了它。
public static void main(String[] args) {
    final int MAX_PRIME = (int) Math.sqrt(Integer.MAX_VALUE);
    List<Integer> primes = sieve(MAX_PRIME);

    int triangularNumber = 0;
    for (int i = 1; i < Integer.MAX_VALUE; i++) {
        triangularNumber += i;
        Map<Integer, Integer> factors = factorize(primes, triangularNumber);
        int total = countDivisors(factors);
        if (total > 500) {
            break;
        }
    }
    System.out.println("The number " + triangularNumber);
}
T(n) = T(n-1) + n
long c=2;
long d=(c*(c+1)/2);

while (numDivs(d)<=500) {
    c++;
    d += c;
}