project euler 108

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;
		}
	}
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值