什么是解决Project Euler#28最有效的方法?

时间:2016-09-17 09:47:44

标签: java performance

数字螺旋对角线

Problem 28

从数字1开始,顺时针方向向右移动,形成一个5乘5螺旋,如下所示:

21 22 23 24 25

20 07 08 09 10

19 06 01 02 11

18 05 04 03 12

17 16 15 14 13

可以验证对角线上的数字之和为101.

以相同方式形成的1001乘1001螺旋中对角线上的数字总和是多少?

问题很容易解决。然而,我总是挑战自己,使表现更好。

经过多次调整后,这就是我最终的方法:

public static long sumOfDiagonals(int n){
    long lastNumber = n * n;
    long sum = 1;           //because the loop starts from the second diagonal number
    long currentNumber = 1; 

    /*
    1- set i to 2
    2- add i to the current number to get the next diagonal number
    3- do step (2) for 4 times because each spiral has 4 angles (diagonal numbers)
    4- increase i by 2 then return to step (2) because the spiral length is getting 2 units bigger each round
    */
    outerLoop:
    for(int i = 2; ;i+=2){ 
        for(int j = 0; j < 4; j++){
            currentNumber +=i;
            if(currentNumber > lastNumber) break outerLoop;                
            sum += currentNumber;
        }
    }
    return sum;
}

我做得太多了

  • 在math.stackexchange.com上发了一个问题,询问对角线1,3,5,...... 25上的数字是否可以表示为序列或公式?但那里我没有得到任何运气/答案。
  • 通过ProjectEuler网站上的答案搜索,寻找更好的算法。

1 个答案:

答案 0 :(得分:0)

对于每个奇数宽度的正方形(1 - 3 - 5 ......),螺旋在右上角结束,为n 2(因为整个正方形中有n 2个数字)。

对于下一个奇数平方,加上长度为n + 1的4个边,因此得到的边是n + 2.

n² + 1, ..., n² + n + 1 (right bottom)
n² + n + 2, ..., n² + 2n + 2 (left bottom)
n² + 2n + 3, ..., n² + 3n + 3 (left top)
n² + 3n + 4, ..., n² + 4n + 4 (right top)

检查:(n + 2)²=n²+ 4n + 4;

添加到先前的对角线总和n:

4n² + 10n + 10

检查:

1->24, 3->76, 5->160, ...
1, 25, 101, 261, ...

diagonal_sum(n) = 1 + Sum(i from 1 to n-2 by 2) 4i² + 10i + 10 

创建一个公式适合数学运算,所以我把它留给你,使用may(2k + 1),或求解3 rd 度多项式的系数。

关于答案:使用David Wallaces的公式。