project euler 12

Problem 12


Highly divisible triangular number

The sequence of triangle numbers is generated by adding the natural numbers. So the 7th triangle number would be 1 + 2 + 3 + 4 + 5 + 6 + 7 = 28. The first ten terms would be:

1, 3, 6, 10, 15, 21, 28, 36, 45, 55, …

Let us list the factors of the first seven triangle numbers:

 1: 1
 3: 1,3
 6: 1,2,3,6
10: 1,2,5,10
15: 1,3,5,15
21: 1,3,7,21
28: 1,2,4,7,14,28

We can see that 28 is the first triangle number to have over five divisors.

What is the value of the first triangle number to have over five hundred divisors?


高度可约的三角形数

三角形数数列是通过逐个加上自然数来生成的。例如,第7个三角形数是 1 + 2 + 3 + 4 + 5 + 6 + 7 = 28。三角形数数列的前十项分别是:

1, 3, 6, 10, 15, 21, 28, 36, 45, 55, …

让我们列举出前七个三角形数的所有约数:

 1: 1
 3: 1,3
 6: 1,2,3,6
10: 1,2,5,10
15: 1,3,5,15
21: 1,3,7,21
28: 1,2,4,7,14,28

我们可以看出,28是第一个拥有超过5个约数的三角形数。

第一个拥有超过500个约数的三角形数是多少?

package projecteuler;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;

import org.junit.Test;

public class Prj12 {

	/**
	 * The sequence of triangle numbers is generated by adding the natural
	 * numbers. So the 7^(th) triangle number would be 1 + 2 + 3 + 4 + 5 + 6 + 7
	 * = 28. The first ten terms would be:
	 * 
	 * 1, 3, 6, 10, 15, 21, 28, 36, 45, 55, ...
	 * 
	 * Let us list the factors of the first seven triangle numbers:
	 * 
	 * 1: 1 3: 1,3 6: 1,2,3,6 10: 1,2,5,10 15: 1,3,5,15 21: 1,3,7,21 28:
	 * 1,2,4,7,14,28
	 * 
	 * We can see that 28 is the first triangle number to have over five
	 * divisors.
	 * 
	 * What is the value of the first triangle number to have over five hundred
	 * divisors?
	 */
	@Test
	public void test() {

		IntegerDivisor div = new IntegerDivisor();
		long sum = 1 + 2;
		for (int i = 3;; i++) {
			sum += i;

			div.divisor(sum);

			int count = 1;
			for (Entry<Long, Integer> entry : div.primeMap.entrySet()) {
				count *= (entry.getValue() + 1);
			}

			if (i % 10000 == 0) {

				System.out.println("num=" + i + " ,sum= " + sum + ",count="
						+ count);
			}
			if (count > 500) {
				System.out.println("num=" + i + ", sum=" + sum);
				System.out.println(div);
				break;
			}
			div.clear();
		}
	}

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

		@Override
		public String toString() {

			StringBuilder sb = new StringBuilder();
			for (Entry<Long, Integer> entry : primeMap.entrySet()) {
				sb.append(entry.getKey().toString() + "="
						+ entry.getValue().toString() + "\n");
			}

			for (int i = 0; i < primeList.size(); i++) {
				sb.append(primeList.get(i) + "--->");
			}
			return sb.toString();
		}

		public Long getLargestPrime() {
			return primeList.get(primeList.size() - 1);
		}

	}

}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值