[题目] 输出如图的螺旋矩阵:
1 2 3 4
12 13 14 5
11 16 15 6
10 9 8 7
[附加题] 输入一个正整数 N,输出以 N 为边长的螺旋矩阵。(比如上图就是 N 为 4 的结果)
1. 初步思路:
-
创建二维列表去存储数字, 最后输出
-
找出存数字的规律: 用(i, j)表示列表下标, 则:
i 的运动规律是: 0 -> 1-(n-1) -> (n-1) -> (n-2)-1 -> 1 -> 2-(n-2) -> (n-2) ...
j 的运动规律是: 0-(n-1) -> (n-1) -> (n-2)-0 -> 0 -> 1-(n-2) -> (n-2) ...
但是这样太复杂了, pass
2. 参考答案的解题思路, 自己实现代码:
[解题思路]:
-
由图可知,螺旋数组中的数字运动方向依次 右 -> 下 -> 左 -> 上 -> 右 这样的循环,在合适的条件下变换累加方向即可。
-
变换方向的条件有两个,一是遇到数组边界,二是下一位置被其他数占据。
-
可用一个二维列表存储数据,按照规则将列表中填上数字,最后再输出
实现代码如下:
#! /usr/bin/env python
# coding = utf-8
def switch(list, i, j):
#1. boundry 2. already have data
if i >= n or j >= n:
return True
elif list[i][j] != 0:
return True
else:
return False
def switch_direction(direction):
# direction: right -> down -> left -> up
if direction == 'right':
return 'down'
elif direction == 'down':
return 'left'
elif direction == 'left':
return 'up'
elif direction == 'up':
return 'right'
else:
pass
def next_coordinary(direction, i, j):
if direction == 'right':
return i, j+1
elif direction == 'down':
return i+1, j
elif direction == 'left':
return i, j-1
elif direction == 'up':
return i-1, j
if __name__ == "__main__":
n = int(input("please input n: "))
list = [[0 for i in range(n)] for j in range(n)]
i = 0
j = 0
direction = 'right'
for k in xrange(1, n ** 2 + 1):
list[i][j] = k
if k == n**2:
break
i1, j1 = next_coordinary(direction, i, j)
while switch(list, i1, j1):
direction = switch_direction(direction)
i1, j1 = next_coordinary(direction, i, j)
i, j = i1, j1
for i in range(n):
for j in range(n):
print "{}\t".format(list[i][j]),
print '\n'
3. 作者给出的参考代码:
class Spiral:
def __init__(self, N):
# 构造一个二维数组
self.matrix = [[None for i in range(N)] for j in range(N)]
# 起始行列数
self.row = 0
self.col = 0
# 数组的边界值
self.max_row = N
# 更换方向的标记
self.mark = 0
# 按需取出数组运动方向
def derection(self, mark):
around = [
[self.row, self.col+1], # 向右
[self.row+1, self.col], # 向下
[self.row, self.col-1], # 向左
[self.row-1, self.col] # 向上
]
return around[mark%4]
# 针对目前位置,获取下一位置的行列数
# 下一位置为边界则更换方向
# 下一位置已经有元素则更换方向
def next(self):
# 下一位置
i = self.derection(mark=self.mark)
# 判断是否更换方向,不更换则更新 self.row / self.col
if -1 not in i and self.max_row not in i:
if self.matrix[i[0]][i[1]] is None:
self.row,self.col = i
return None
# 更换方向
self.mark += 1
return self.next()
def solution(self):
# 逐一取出 1 到 n^2 值
for i in range(1,self.max_row**2+1):
# 按行列赋值
self.matrix[self.row][self.col] = i
# 退出条件
if i == self.max_row**2:
break
# 更新行列值
self.next()
# 打印结果
for r in self.matrix:
for c in r:
print('{0:^{1}}'.format(c,self.max_row), end=' ')
print('\n')
if __name__ == '__main__':
n = int(input('>>>'))
s = Spiral(n)
s.solution()
4.答案最简洁的写法
n=int(raw_input("N:"))
a=[[0 for i in range(1,n+1)]for j in range(1,n+1)]
x,y,i,j=0,0,0,0
while a[i][j]==0 :
y+=1
a[i][j]=y
if j<n-1 and a[i][j+1]==0 and (i==0 or (i>0 and a[i-1][j]!=0 )):
##括号内容可保证第四个elif从下往上的顺序正常进行
j+=1
elif i<n-1 and a[i+1][j]==0:
i+=1
elif j>0 and a[i][j-1]==0:
j-=1
elif i>0 and a[i-1][j]==0:
i-=1
for b in a:
print
for c in b:
print c,