这里有 2 个备选方案:
1)遍历所有三角形并在currentSum
(三角形数)有超过THRESHOLD
除数
时停止
Time: 1.79 seconds。
public class P12 {
final static int THRESHOLD = 500;
public static void main(String[] args) {
System.out.println(getTriangle());
}
public static long getTriangle() {
int n = 1;
long currentSum = 0;
while (!hasOverXDivisors(currentSum, THRESHOLD)) {
currentSum += n;
n++;
}
return currentSum;
}
private static boolean hasOverXDivisors(long nr, int threshold) {
if ( nr <= threshold ) {
return false;
}
int divisors = 0;
int i;
int sqrt = (int) Math.sqrt(nr);
for ( i = 1 ; i <= sqrt ; i++ ) {
if ( nr % i == 0 ) {
divisors+=2; // E.g.: (2, n/2), (3, n/3)
}
}
if ( sqrt*sqrt == nr ){ // it was counted twice
divisors--;
}
if ( divisors > threshold ) {
return true;
}
return false;
}
}
2) 它基于互质数属性。三角形数等于n*(n+1)/2
where n
and n+1
are coprimes => n
and (n+1)/2
are coprimes or n/2
and n+1
are coprimes (这取决于n
是偶数还是奇数)。
时间:61 毫秒。
public class P12 {
final static int THRESHOLD_DIVISORS = 500;
public static void main(String[] args) {
System.out.println(getTriangle(1));
}
public static long getTriangle(int n) {
long numberOfDivisors = 0;
long firstCoprime, secondCoprime;
while (true) {
if ( n % 2 == 0 ) {
firstCoprime = getNumberOfDivisors(n/2);
secondCoprime = getNumberOfDivisors(n+1);
} else {
firstCoprime = getNumberOfDivisors(n);
secondCoprime = getNumberOfDivisors((n+1)/2);
}
numberOfDivisors = firstCoprime * secondCoprime;
if ( numberOfDivisors > THRESHOLD_DIVISORS ) {
return n*(n+1)/2;
}
n++;
}
}
private static long getNumberOfDivisors(long nr) {
int divisors = 0;
int i;
int sqrt = (int) Math.sqrt(nr);
for ( i = 1 ; i <= sqrt ; i++ ) {
if ( nr % i == 0 ) {
divisors+=2; // E.g.: (2, n/2), (3, n/3)
}
}
if ( sqrt*sqrt == nr ){ // it was counted twice
divisors--;
}
return divisors;
}
}
我使用整数作为getTriangle()
方法的参数,以便更容易改进此方法。您可以决定从大1
于此特定情况的值开始。在这种情况下,您可以将时间减少至少 3 倍。