python 实现魔方数阵
本帖最后由 smarth 于 2020-12-10 19:34 编辑#首发时间:2020.12.10.19:25
#本帖目的:
# 0、分享”魔方数阵“的实现方法
# 1、探讨是否有更优解
# 2、获得一些问题的解答(问题在代码注释中)
注:代码分两部分,一为我自己的解法,一为老师讲解后我按其思路敲下的。
两段代码总体思路一致,老师的做法更老练
魔方数阵定义:
整数阵,边长为N*N,元素取值为1至N*N,1在左上角,呈顺时针方向依次放置各元素。
4阶魔方数阵示例:
关键思路:
0、创建n*n 的二维数组(列表)来存储数字。
1、赋值分为4部分(4方向),依次为 右 -> 下 -> 左 -> 上 -> 右
2、边界需要注意(超出数组长度、已有值)
3、 赋值顶角数字后需要为转向做2个准备(详见代码)
我的代码:
n = int(input())
#获取批题系统给出的阶数
a = [(*n) for i in range(n)]
#创建二维数组并赋初值 None, 这里可以用 0 代替
# 关于二维数组的创建我昨天发的主题有详细探讨,尚存在问题,欢迎大佬去指点
number, count, i, j = 1, 0, 0, 0
#number 为赋值变量count 判定调用哪个函数 i、j分别代表行、列
def isNotObstacles(i, j):
#该函数判断下一个位置是否是边界(超出数组长度、下一个位置已赋值)
#是返回 0 不是返回 1
if(i >= n or j >= n):
return 0
elif(i < 0 or j < 0):
return 0
elif (a != None):
return 0
return 1
def run():
#这个函数的代码会多次用到,直接定义函数避免代码重复
global number
#关于python中的全局变量我尚不熟悉,恳请大佬指定
#如果这里的number 在最初定义变量时如果声明为global number
#在这里显示无声明,必须在这里再次声明
#c语言在main函数外声明的变量即为全局变量,而python似乎不是?
#请大佬帮我解答以上两个疑惑
a = number
number += 1
def right():
#定义向右赋值的函数,一下down left up 类似
global i, j, count
if(count != 0):
#拐角处的第一个准备
i += 1
#缺少这一步会出错,按理不需要,请大佬解释
j += 1
#拐角需要列数加1,否则会陷入死循环,第一次不需要
if(not isNotObstacles(i, j)):
i -= 1
#转变方向,为拐角处的第二个准备
while(isNotObstacles(i, j)):
#赋值且列数加一(转向下一个位置)
run()
j += 1
def down():
global i, j
i += 1
if(not isNotObstacles(i, j)):
j -= 1
while(isNotObstacles(i, j)):
run()
i += 1
def left():
global i, j
j -= 1
if(not isNotObstacles(i, j)):
i -= 1
while(isNotObstacles(i, j)):
run()
j -= 1
def up() :
global i, j
i -= 1
if(not isNotObstacles(i, j)):
j += 1
while(isNotObstacles(i, j)):
run()
i -= 1
def main():
global count
#利用count对4取模判定调用哪个函数
while(number <= n*n):
if(count % 4 == 0):
right()
elif(count % 4 == 1):
down()
elif(count % 4 == 2):
left()
else:
up()
count += 1
main()
#以上为魔方数阵的所有代码
# 由于题目要求需要输出到文件中,因此有下列代码。
out = open("file.out","w+", encoding = "gbk")
for i in range(n):
for j in range(n):
if(j == n - 1):
print("%5d"%a, end ='\n', file = out )
continue
print("%5d"%a, end ='', file = out)
out.close()
老师的代码:
#忘了一个标注,python的小知识
#用“and”连接两个条件,第一个条件为假第二个条件就不判断,直接退出
n = int(input())
dir = 0
#用dir代替我的count
mat = [ * n for i in range(n)]
i, j = 0, 0
for k in range(1, n * n + 1):
#k相当于我的number
mat = k
#下面的代码用来寻找下一个位置
while(k < n*n):
#当k = n*n即倒数第一个时不需要寻找下一个位置
if(dir == 0):#相对于我的right()
if(j < n - 1 and mat == None ):
#我大费周章定义了函数判断边界老师一个条件判断就over了
j += 1
break
else:
i += 1 #拐角
dir = 1#换方向
break
elif(dir == 1):
if(i < n - 1 and mat == None):
i += 1
break
else:
j -= 1
dir = 2
break
elif(dir == 2):
if(j > 0 and mat == None):
j -= 1
break
else:
i -= 1
dir = 3
break
elif(dir == 3):
if(i > 0 and mat == None):
i -= 1
break
else:
j += 1
dir = 0
break
for i in range(len(mat)):
print(mat)
谢谢,学习了! 学习一下 在C语言的世界里,这个题叫做蛇形填数 好像是弄过,先确定是第几圈的数,然后有公式填充一下就行了 蛇形填数
页:
[1]