当前位置:首页 » Project Euler » 详细页

Hexagonal tile differences 题号:128 难度: 55 中英对照

A hexagonal tile with number 1 is surrounded by a ring of six hexagonal tiles, starting at "12 o'clock" and numbering the tiles 2 to 7 in an anti-clockwise direction.

New rings are added in the same fashion, with the next rings being numbered 8 to 19, 20 to 37, 38 to 61, and so on. The diagram below shows the first three rings.

By finding the difference between tile n and each of its six neighbours we shall define PD(n) to be the number of those differences which are prime.

For example, working clockwise around tile 8 the differences are 12, 29, 11, 6, 1, and 13. So PD(8) = 3.

In the same way, the differences around tile 17 are 1, 17, 16, 1, 11, and 10, hence PD(17) = 2.

It can be shown that the maximum value of PD(n) is 3.

If all of the tiles for which PD(n) = 3 are listed in ascending order to form a sequence, the 10th tile would be 271.

Find the 2000th tile in this sequence.


Solution

注意到从$1$出发向上($1->2->8$这个方向),这条线上所有格子($1,2,8,20,...$)以及右侧的格子($7,19,37,...$)可能满足题目要求。 其他所有格子$x$的邻居中都包含$x+1$和$x-1$以及两侧的$y,y+1$以及$z,z+1$,显然差值是$1,-1,x-y,x-y+1,x-z,x-z+1$,前两者均不是素数,中间两者最多有1个素数,后两者最多有1个素数,综合来看$x$的邻居的差值最多有2个素数,故不符合题目要求。 枚举$2->8>20$,并同时检查右侧的格子$7->19->37$,判断是否满足题意即可。

Code


public final class p128 {
    
    public static void main(String[] args) {
        long start=System.nanoTime();
        String result = run();        
        long end=System.nanoTime();
        System.out.println(result);
        System.out.println( (end-start)/1000000 + "ms" );
    }
    
    public static String run(){
    	return solve(2000)+"";
    }

	public static long solve(int N) {
		for (long n = 2, p = 8, m = 6;; m += 6, p += m) {
			if (isPrime(m + 5) && isPrime(m + 7) && isPrime(2 * m + 17)
					&& (++n == N))
				return p;
			if (isPrime(m + 5) && isPrime(m + 11) && isPrime(2 * m + 5)
					&& (++n == N))
				return p + m + 5;
		}
	}

	// prime number checking function
	public static boolean isPrime(long n) {
		if (n < 2)
			return false;
		if (n == 2 || n == 3)
			return true;
		if (n % 2 == 0 || n % 3 == 0)
			return false;
		long sqrtN = (long) Math.sqrt(n) + 1;
		for (long i = 6L; i <= sqrtN; i += 6) {
			if (n % (i - 1) == 0 || n % (i + 1) == 0)
				return false;
		}

		return true;
	};
}
14516824220
145ms