用python来解 PAT 1050螺旋矩阵-25-满分无超时

根据题意:给定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,00,10,2
1,01,11,2
2,02,12,2
3,03,13,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))

提交结果:

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值