螺旋填充方阵
【问题】用1…n2n^2n2的自然数顺时针方向螺旋填充一个n阶方阵。
当 n = 7 的时候,如下:

先做一个空的二维数组代表方阵。
始终记录当前的位置,当前填充的数字,当前的填充方向。
当遇到阻力(出界或者撞上了已填的数字)以后,改变填充的方向。
from collections import namedtuple
Posi = namedtuple('Posi', 'row col') # 位置包含行号和列号
Dire = namedtuple('Dire', 'dr dc') # 移动方向包含行的变化、列的变化
def next_dire(x):
return {
Dire(0,1): Dire(1,0),
Dire(1,0): Dire(0,-1),
Dire(0,-1): Dire(-1,0),
Dire(-1,0): Dire(0,1)
}[x]
def next_posi(p, d):
return Posi(p.row + d.dr, p.col + d.dc)
def fang(n):
da = [[0 for j in range(n)] for i in range(n)]
p = Posi(0,0)
d = Dire(0,1)
c = 1
while c <= n*n:
da[p.row][p.col] = c
c += 1
p2 = next_posi(p,d)
if p2.row < 0 or p2.row == n or p2.col < 0 or p2.col == n \
or da[p2.row][p2.col] != 0:
d = next_dire(d)
p2 = next_posi(p,d)
p = p2
return da
def disp(x):
for row in x:
for i in row:
print("{:3d}".format(i), end = ' ')
print()
if __name__ == '__main__':
disp(fang(7))
为了更清楚地表示位置,方向这些概念,使用了命名元组。
在计算当前方向转向后的下一个方向时,用了映射。
这里的方向计算还可以用复数乘法的性质,以数学公式表达向右转的概念。
如果不喜欢抽象。也可以老老实实地:
向右走,然后向下走,然后向左走,然后向上走,然后向右走…
这样代码会长一些:
def fang(n):
da = [[0 for j in range(n)] for i in range(n)]
p = (0,0)
c = 1
def go_right(p, c):
da[p[0]][p[1]] = c
p2 = (p[0],p[1]+1)
if p2[1] == n or da[p2[0]][p2[1]] != 0: raise Exception("No way")
return p2, c+1
def go_down(p,c):
da[p[0]][p[1]] = c
p2 = (p[0]+1,p[1])
if p2[0] == n or da[p2[0]][p2[1]] != 0: raise Exception("No way")
return p2, c+1
def go_left(p,c):
da[p[0]][p[1]] = c
p2 = (p[0],p[1]-1)
if p2[1] < 0 or da[p2[0]][p2[1]] != 0: raise Exception("No way")
return p2, c+1
def go_up(p,c):
da[p[0]][p[1]] = c
p2 = (p[0]-1,p[1])
if p2[0] < 0 or da[p2[0]][p2[1]] != 0: raise Exception("No way")
return p2, c+1
def loop_do(f, p, c):
try:
while True:
p, c = f(p, c)
except:
return p, c
while True:
p, c = loop_do(go_right, p, c)
if c >= n*n: break;
p, c = loop_do(go_down, p, c)
if c >= n*n: break;
p, c = loop_do(go_left, p, c)
if c >= n*n: break
p, c = loop_do(go_up, p, c)
if c >= n*n: break;
return da
def disp(x):
for row in x:
for i in row:
print("{:3d}".format(i), end = ' ')
print()
if __name__ == '__main__':
disp(fang(7))
本文介绍如何使用Python3将1到n²的自然数按顺时针方向螺旋填充n阶方阵。通过建立二维数组,记录当前位置、填充数字及填充方向,遇到边界或已填充位置时改变方向。利用映射处理方向转换,也可用复数乘法规则或直接定义四个基本方向来实现。
螺旋填充方阵&spm=1001.2101.3001.5002&articleId=100986633&d=1&t=3&u=e53e93f9b2cc41ab9c09d8fa2f77f4e5)
1323

被折叠的 条评论
为什么被折叠?



