求螺旋矩阵对角线的和

注:不再标明题目出处,仅供学习交流

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,代入得到结果。

注意,程序里的平方与表达式里的平方表示不一样,所以需要改变一下。 

^ 在程序里表示位操作,所以会得到不一致的结果。

并不是公式有问题,而是程序与公式的表示方式上不同,修改过来就可以了。


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值