求螺旋矩阵对角线的和
2014-09-25 10:20
148 查看
注:不再标明题目出处,仅供学习交流
Starting with the number 1 and moving to the right in a clockwise direction a 5 by 5 spiral is formed as follows:
21 22 23 24 25
20 7 8 9 10
19 6 1 2 11
18 5 4 3 12
17 16 15 14 13
It can be verified that the sum of the numbers on the diagonals is 101.
What is the sum of the numbers on the diagonals in a 1001 by 1001 spiral formed in the same way?
求螺旋矩阵对角线的和
分析:
这里有两个方法:
第一种是构建这么一个螺旋矩阵,然后计算它的对角线值
构建矩阵时,可以从中间开始,然后右移一格,此时进入一个新的矩形圈。
往下移两格,再往左移两格,再往上移两格,再往右移两格,再往右移一格,又进入一个新的矩形圈。
此时需要往下移四格,,,,
当进入一个新的矩形圈后,步长为前面步长 + 2
代码如下:
然后计算对角线之和:
那么就可以得到最后的结果。
第二种是根据每次累积的数值关系,得到一个公式,然后直接求
根据第一种方法,构建螺旋矩阵时,所采用的步长,可以得到对角线上的元素值如下:
1,3,5,7,9,13,17,21,25,33,41,49,57...
若每个元素减少1,得到一个新的序列:
0,2,4,6,8,12,16,20,24,32,40,48,56 ...
都是偶数,~~,而且从2开始,连续4个数的差是相同的
那么可以取出0, 8, 24, 56, ...做为一个新的序列,我把它命名为 C(4, n)
,n 取值从0开始依次增大
那么有,C(4, 0) = 0, C(4, 1) = 8, C(4, 2) = 24, C(4, 3) = 48, ....
按照从原序列取出来的规律,分解一下当前序列的元素,有:
C(4, 1) = 2 + 2 + 2 + 2 = 2 * 4
C(4, 2) = C(4, 1) + 4 + 4 + 4 + 4 = 2 * 4 + 4 * 4
C(4, 3) = C(4, 2) + 6 + 6 + 6 +6 = 2 * 4 + 4 * 4 + 6 * 4
...
那么有 C(4, n) = C(4, n - 1) + 2*n * 4 = C(4, n - 1) + 8 * n
运用迭代法,得到:C(4, n) = C(4, 0) + 8 * 1 + 8*2 + ... + 8*n = 8 * (1 + 2 + ... + n) =4 * n * (n+1)
计算原序列的和:S = S(4, n) + extra
S(4, n) = S(4, n-1) + C(4, n-1) + n * 2 + C(4, n-1) + n * 2*2 + C(4, n-1) + n * 2*3 + C(4, n-1) + n * 2*4
= S(4, n-1) + C(4, n-1) * 4 + n * 2 * (1 + 2 +3 +4)
= S(4, n-1) + C(4, n-1) * 4 + 20 * n
运用迭代法,得到:S(4, n) = S(4, 0) + C(4, 0) * 4 + 20 * 1 + C(4,1) * 4 + 20*2 + ... + C(4, n-1) * 4 + 20 * n
= 4 * (C(4, 0) + C(4, 1) + ... + C(4, n-1)) + 20 * (1 + 2 + ... + n)
= 16 * ( 1*2 + 2*3 + ... + n * (n-1)) + 10 * n * (n+1)
= 16 * (1^2 + 1 + 2^2 + 2 + 3^2 + 3 + ... + (n-1)^2 + n-1) + 10*n*(n+1)
= 16 * ((n-1)*n*(2*(n-1)+1) / 6 + (n-1)*n) / 2) + 10*n*(n+1) # 这里利用了平方和的和公式
= 8 * n * (n-1) * (2*n - 1) / 3 + 8 * n * (n-1) + 10*n*(n+1)
因为每一项都少了1,且这里一次性计算4个数,所以extra = 4*n + 1
得到完整的计算公式:S = 8 * n * (n-1) * (2*n - 1) / 3 + 8 * n * (n-1) + 10*n*(n+1) + 4*n + 1
再用语言表示出来,就可以计算到最终结果,这里的n 相对于题目中的1001 / 2 = 500
还有另外一种计算方法:
观察矩阵中右上角元素:1,9,25,49,... 奇数平方列
其余每矩形三元素(其中一个已经计算了)计算方法,前一奇数平方 + 下一偶数 * 所在位置
然后把所有元素相加,即可得到结果。
设定level : 1->n, step = 2, 给出的序列通项为:level ^ 2
这里依然每次计算4元素: Ccurr = level^2
Scurr = curr + curr + (level+1) + curr + (level+1)*2 + curr + (level+1)*3
= 4*curr + (level+1)*6
= 4*level^2 + 6*level + 6
引用,连续奇数和公式为:S(2*n-1) = n ^ 2, n为从1开始连续奇数的个数
连续奇数平方和公式为:S((2*n-1)^2) = n*(2*n+1)*(2*n-1) / 3,n为从1开始连续奇数的个数
不知道这些公式的可以在搜索一下,网上有详细的推导过程。
S = S((n-2)^2) + Cn # 需要将 n-2 转化为奇数的个数:((n-2 +1) /2),然后代入即得到如下公式
= 4*((n-2 +1) /2)*(2*((n-2 +1) /2)+1)*(2*((n-2 +1) /2)-1) / 3 + 6 * ((n-2 +1) /2)^2 + 6*((n-2 +1) /2) + n ^ 2
这里的n 为1001,代入得到结果。
注意,程序里的平方与表达式里的平方表示不一样,所以需要改变一下。
^ 在程序里表示位操作,所以会得到不一致的结果。
并不是公式有问题,而是程序与公式的表示方式上不同,修改过来就可以了。
Starting with the number 1 and moving to the right in a clockwise direction a 5 by 5 spiral is formed as follows:
21 22 23 24 25
20 7 8 9 10
19 6 1 2 11
18 5 4 3 12
17 16 15 14 13
It can be verified that the sum of the numbers on the diagonals is 101.
What is the sum of the numbers on the diagonals in a 1001 by 1001 spiral formed in the same way?
求螺旋矩阵对角线的和
分析:
这里有两个方法:
第一种是构建这么一个螺旋矩阵,然后计算它的对角线值
构建矩阵时,可以从中间开始,然后右移一格,此时进入一个新的矩形圈。
往下移两格,再往左移两格,再往上移两格,再往右移两格,再往右移一格,又进入一个新的矩形圈。
此时需要往下移四格,,,,
当进入一个新的矩形圈后,步长为前面步长 + 2
代码如下:
curr = 1
step = 0 x = y = n / 2 m[x][y] = curr curr += 1 while curr < n ** 2: x += 1<span style="white-space:pre"> </span># 进入下一个矩形 step += 2<span style="white-space:pre"> </span># 步长 for i in xrange(step):<span style="white-space:pre"> </span># 对矩形边界向下填充 m[x][y + i] = curr curr += 1 y += step - 1<span style="white-space:pre"> </span># 对齐 x -= 1<span style="white-space:pre"> </span># for i in xrange(step):<span style="white-space:pre"> </span># 对矩形边界向左填充 m[x - i][y] = curr curr += 1 x -= step - 1<span style="white-space:pre"> </span># 对齐 y -= 1 for i in xrange(step):<span style="white-space:pre"> </span># 对矩形边界向上填充 m[x][y - i] = curr curr += 1 y -= step - 1<span style="white-space:pre"> </span># 对齐 x += 1 for i in xrange(step):<span style="white-space:pre"> </span># 对矩形边界向右填充 m[x + i][y] = curr curr += 1 x += step - 1<span style="white-space:pre"> </span>对齐按照此方法,可以构建一个螺旋矩阵。
然后计算对角线之和:
res = 0 for i in xrange(n): res += m[i][i] + m[i][n - i - 1] print res - 1由此计算得到的结果,把中间的1 重复了一次,所以结果需要去掉
那么就可以得到最后的结果。
第二种是根据每次累积的数值关系,得到一个公式,然后直接求
根据第一种方法,构建螺旋矩阵时,所采用的步长,可以得到对角线上的元素值如下:
1,3,5,7,9,13,17,21,25,33,41,49,57...
若每个元素减少1,得到一个新的序列:
0,2,4,6,8,12,16,20,24,32,40,48,56 ...
都是偶数,~~,而且从2开始,连续4个数的差是相同的
那么可以取出0, 8, 24, 56, ...做为一个新的序列,我把它命名为 C(4, n)
,n 取值从0开始依次增大
那么有,C(4, 0) = 0, C(4, 1) = 8, C(4, 2) = 24, C(4, 3) = 48, ....
按照从原序列取出来的规律,分解一下当前序列的元素,有:
C(4, 1) = 2 + 2 + 2 + 2 = 2 * 4
C(4, 2) = C(4, 1) + 4 + 4 + 4 + 4 = 2 * 4 + 4 * 4
C(4, 3) = C(4, 2) + 6 + 6 + 6 +6 = 2 * 4 + 4 * 4 + 6 * 4
...
那么有 C(4, n) = C(4, n - 1) + 2*n * 4 = C(4, n - 1) + 8 * n
运用迭代法,得到:C(4, n) = C(4, 0) + 8 * 1 + 8*2 + ... + 8*n = 8 * (1 + 2 + ... + n) =4 * n * (n+1)
计算原序列的和:S = S(4, n) + extra
S(4, n) = S(4, n-1) + C(4, n-1) + n * 2 + C(4, n-1) + n * 2*2 + C(4, n-1) + n * 2*3 + C(4, n-1) + n * 2*4
= S(4, n-1) + C(4, n-1) * 4 + n * 2 * (1 + 2 +3 +4)
= S(4, n-1) + C(4, n-1) * 4 + 20 * n
运用迭代法,得到:S(4, n) = S(4, 0) + C(4, 0) * 4 + 20 * 1 + C(4,1) * 4 + 20*2 + ... + C(4, n-1) * 4 + 20 * n
= 4 * (C(4, 0) + C(4, 1) + ... + C(4, n-1)) + 20 * (1 + 2 + ... + n)
= 16 * ( 1*2 + 2*3 + ... + n * (n-1)) + 10 * n * (n+1)
= 16 * (1^2 + 1 + 2^2 + 2 + 3^2 + 3 + ... + (n-1)^2 + n-1) + 10*n*(n+1)
= 16 * ((n-1)*n*(2*(n-1)+1) / 6 + (n-1)*n) / 2) + 10*n*(n+1) # 这里利用了平方和的和公式
= 8 * n * (n-1) * (2*n - 1) / 3 + 8 * n * (n-1) + 10*n*(n+1)
因为每一项都少了1,且这里一次性计算4个数,所以extra = 4*n + 1
得到完整的计算公式:S = 8 * n * (n-1) * (2*n - 1) / 3 + 8 * n * (n-1) + 10*n*(n+1) + 4*n + 1
再用语言表示出来,就可以计算到最终结果,这里的n 相对于题目中的1001 / 2 = 500
还有另外一种计算方法:
观察矩阵中右上角元素:1,9,25,49,... 奇数平方列
其余每矩形三元素(其中一个已经计算了)计算方法,前一奇数平方 + 下一偶数 * 所在位置
然后把所有元素相加,即可得到结果。
设定level : 1->n, step = 2, 给出的序列通项为:level ^ 2
这里依然每次计算4元素: Ccurr = level^2
Scurr = curr + curr + (level+1) + curr + (level+1)*2 + curr + (level+1)*3
= 4*curr + (level+1)*6
= 4*level^2 + 6*level + 6
引用,连续奇数和公式为:S(2*n-1) = n ^ 2, n为从1开始连续奇数的个数
连续奇数平方和公式为:S((2*n-1)^2) = n*(2*n+1)*(2*n-1) / 3,n为从1开始连续奇数的个数
不知道这些公式的可以在搜索一下,网上有详细的推导过程。
S = S((n-2)^2) + Cn # 需要将 n-2 转化为奇数的个数:((n-2 +1) /2),然后代入即得到如下公式
= 4*((n-2 +1) /2)*(2*((n-2 +1) /2)+1)*(2*((n-2 +1) /2)-1) / 3 + 6 * ((n-2 +1) /2)^2 + 6*((n-2 +1) /2) + n ^ 2
这里的n 为1001,代入得到结果。
注意,程序里的平方与表达式里的平方表示不一样,所以需要改变一下。
^ 在程序里表示位操作,所以会得到不一致的结果。
并不是公式有问题,而是程序与公式的表示方式上不同,修改过来就可以了。
相关文章推荐