根据题意:给定N个整数,按照非递增的顺序填充进m行n列的螺旋矩阵(左上角开始螺旋),要求m,n满足:m×n 等于 N;m≥n;且 m−n 取所有可能值中的最小值。
先分析,这个题目大概分两个步骤:先求m,n,再进行螺旋填充,我的代码分三步,求出m,n后先生成了一个m行n列的全0矩阵,然后再进行填充。
我的求m,n的方法是用的二分法加循环,但是这种方法会超时,因为计算次数太多,所以我改用先求根的方法,比二分法简单太多了,至于生成全0矩阵,两个for循环就ok了,当然也可以直接用列表生成式,最后填充才是最难的,想了很久,发现如果不建坐标系是做不出来的(也可能是我太菜了),所以只能建坐标系,打了下草稿,发现建了坐标系之后一切都豁然开朗:
0,0 | 0,1 | 0,2 |
1,0 | 1,1 | 1,2 |
2,0 | 2,1 | 2,2 |
3,0 | 3,1 | 3,2 |
就以4*3的矩阵为例,螺旋填充顺序是由(0,0)开始,因为行为y,列为x,所以(0,0)->(y,x),向右填充过程中x+1,x等于列-1时停止,向下填充,y+1,y等于行-1时停止,向左填充,x-1,x等于0时停止,向上填充,y-1,外圈填充结束后,x,y分别加一,继续进行内圈填充,按照这个逻辑,代码如下:
import math
n = int(input()) # 需填充的正整数数量
l = list(map(int, input().split()))
l.sort()
l.reverse()# 得到待填充数的非递增序列
# 求m,n
num = math.sqrt(n)
if num % 1 == 0:
column = row = int(num)
else:
row = int(num) + 1
while n % row != 0:
row += 1
column = n // row
# row = 0
# column = 0
# min_v = n
# for i in range(1, int(n / 2)):#二分法
# if n % i == 0 and abs(n // i - i) < min_v:
# min_v = abs(n // i - i)
# row = max(n // i, i)
# column = min(n // i, i)
# else:
# continue #超时案例
# 生成一个全0矩阵
ling = []
for i in range(row):
li = []
for j in range(column):
li.append(0)
ling.append(li) #可以简化成列表生成式ling = [[0]*column for i in range(row)]
left = 0
top = 0
x = 0
y = 0
i = 0
while i<n:
if i == n-1:
ling[y][x] = str(l[i])
i +=1
while x < column - 1 and i < n:
ling[y][x] = str(l[i])
x +=1
i +=1
while y < row - 1 and i < n:
ling[y][x] = str(l[i])
y +=1
i +=1
while x > left and i < n:
ling[y][x] = str(l[i])
x -=1
i +=1
while y > top and i < n:
ling[y][x] = str(l[i])
y -=1
i +=1
left +=1
top +=1
column -=1
row -=1
x +=1
y +=1
for g in ling:
print(' '.join(g))
提交结果: