Diophantine reciprocals I
In the following equation x, y, and n are positive integers.
1x+1y=1n
For n = 4 there are exactly three distinct solutions:
15+120=14
16+112=14
18+18=14
What is the least value of n for which the number of distinct solutions exceeds one-thousand?
NOTE: This problem is an easier version of Problem 110; it is strongly advised that you solve this one first.
丢番图倒数I
在如下方程中,x、y、n均为正整数。
1x+1y=1n
对于n = 4,上述方程恰好有3个不同的解:
15+120=14
16+112=14
18+18=14
使得不同的解的数目超过1000的最小n值是多少?
注意:这个问题是第110题的简单版本;强烈推荐先解决这一题。
package projecteuler;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import junit.framework.TestCase;
public class Prj108 extends TestCase {
public static int LIMIT = 1000;
//public static int LIMIT = 4 * 1000000;
/**
* n < x <= y; x = ny / ( y -n) <= y ===> y >= 2n; so assume x in (n, 2n];
* n(n +i)/i, i in [1, n] ===> numOfDivisors( n * n ) + 1 > 2 * LIMIT;
*/
public void testDiophantineReciprocalsI() {
int i = (int) Math.pow(2, 7);
IntegerDivisor div = new IntegerDivisor();
while (true) {
div.divisor(i);
Map<Long, Integer> map = div.primeMap;
int count = 1;
for (Entry<Long, Integer> entry : map.entrySet()) {
count *= (2 * entry.getValue() + 1);
}
if ((count + 1) > 2 * LIMIT) {
System.out.println("count=" + (count + 1) / 2 + ",n=" + i);
return;
}
div.clear();
i++;
//System.out.println("i=" + i + ",count=" + (count + 1) / 2);
}
}
/**
* over flow
*/
void simpleBrute() {
for (int i = LIMIT;; i++) {
int count = 0;
for (int j = i + 1; j <= 2 * i; j++) {
int n = i;
int x = j;
if ((n * x) % (x - n) == 0) {
count++;
}
}
if (count > LIMIT) {
System.out.println("i====" + i + ",count=" + count);
break;
}
System.out.println("i=" + i + ",count=" + count);
}
}
boolean isPrime(int num) {
if (num <= 10) {
if (num == 2 || num == 3 || num == 5 || num == 7) {
return true;
}
return false;
}
if (num % 2 == 0) {
return false;
}
for (int i = 3; i * i <= num; i = i + 2) {
if (num % i == 0) {
return false;
}
}
return true;
}
public static class IntegerDivisor {
public Map<Long, Integer> primeMap = new HashMap<Long, Integer>();
public List<Long> primeList = new ArrayList<Long>();
public void clear() {
primeList.clear();
primeMap.clear();
}
public void divisor(long num) {
if (num <= 1)
return;
long prime = getPrime(
num,
primeList.size() == 0 ? 2
: primeList.get(primeList.size() - 1));
if (prime < 0) {
primeMap.put(num, 1);
primeList.add(num);
return;
} else {
primeList.add(prime);
int count = 0;
do {
count += 1;
num = num / prime;
} while (num % prime == 0);
primeMap.put(prime, count);
divisor(num);
}
}
private long getPrime(long num, long start) {
for (long i = start; i <= Math.sqrt(num); i++) {
if (num % i == 0) {
return i;
}
}
return -1;
}
}
}