1. 问题描述:
如下图所示,小明用从 1 开始的正整数“蛇形”填充无限大的矩阵。
1 2 6 7 15 …
3 5 8 14 …
4 9 13 …
10 12 …
11 …
…
容易看出矩阵第二行第二列中的数是 5。请你计算矩阵中第 20 行第 20 列的数是多少?这是一道结果填空的题,你只需要算出结果后提交即可。本题的结果为一个整数,在提交答案时只填写这个整数,填写多余的内容将无法得分。
2. 思路分析:
分析题目可以知道我们根据题目中填数字的特点来判断这些数字在填写的时候有什么规律,可以发现从数字2开始存在两个重复性方向的生成动作,第一个方向是左下-下,第二个方向是右上-右,可以知道这两个重复性的方向可以使用两个while循环表示,也就是使用循环分别表示这两个方向,第一个循环终止的条件是往左下走的时候到达了第一列,这个时候就需要往下走一行,第二个循环的终止条件是往上走的时候到了第一行,这个时候需要往右走一行,而且分析题目可以知道因为是第20行与第20列所以答案肯定不是在边界上产生,所以肯定是在两个循环中填数字的时候产生的,所以我们一开始的时候应该设置一个标记f这样当我们在两个循环走的时候发现如果到达了20行与20列那么这个时候就应该退出所有的循环了,所以还需要最外层的一个循环来嵌套两个用来填数字的循环,结合一个标志f来结束所有的循环。并且我们可以声明一个二维列表在填数字的时候将对应位置的结果记录在二维列表中,最终可以输出这个列表判断算法是否存在错误(这个方法还是比较有效检查代码是否存在错误)
3. 代码如下:
if __name__ == '__main__':
# 首先从数字2开始进行循环, 左下-下, 右上-右这两个方向分别为一组, 主要还是找规律吧, 找出循环的共性条件即可
x, y, n = 0, 1, 2
# 设置一个标志来是否找到了这个数字了
f = 1
# 其实可以声明一个列表进行验证看是否生成的数字的位置正确
li = [[0] * 100 for i in range(100)]
li[0][0], li[0][1] = 1, 2
while f:
# 注意y大于0才循环因为在循环中做出了减1的动作
while y > 0:
# 判断是否是找到了, 很明显答案只能够在矩阵的中间范围, 不可能是在边界上得到范围所以在这里判断即可
if x == 19 and y == 19:
f = 0
break
y -= 1
x += 1
# 数字加1
n += 1
li[x][y] = n
# 往下走一行, 注意必须是当没有找到这个数字的时候才可以执行往下或者是往右走一格
if f:
x += 1
n += 1
li[x][y] = n
while x > 0:
# 判断是否是找到了
if x == 19 and y == 19:
f = 0
break
x -= 1
y += 1
n += 1
li[x][y] = n
# 往右边走一格
if f:
y += 1
n += 1
li[x][y] = n
print(n)
for i in range(100):
for j in range(100):
print(li[i][j], end=" ")
print()