smarth 发表于 2020-12-10 19:25

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)

xjshuaishuai 发表于 2020-12-10 21:30

谢谢,学习了!

wan1330 发表于 2020-12-10 21:43

学习一下

pwp 发表于 2020-12-13 23:32

在C语言的世界里,这个题叫做蛇形填数

ymhld 发表于 2020-12-14 11:33

好像是弄过,先确定是第几圈的数,然后有公式填充一下就行了

dork 发表于 2020-12-15 09:50

蛇形填数
页: [1]
查看完整版本: python 实现魔方数阵