wanglyndon 发表于 2023-5-13 19:40:13

有关矩阵列表。

Python编程,求解和为15的棋盘游戏问题。要求将从1到9的九个数填入3×3的棋盘中,使得各行、各列以及两个对角线上的三个数之和均为15,并打印出结果

相信大家都知道这个是很出名的魔法矩阵

# 4 9 2
# 3 5 7
# 8 1 6

这是其中的一个例子

现在请问,这个例子中,数字1在第三行第二列,我的方法是,从1的位置开始,向上两个随后向右一格就是原数字+1的结果,但是如果向上两个随后向右一格后这个数字存在,那么原数字上面一格的数字,等于原数字的值+1

现在问,如果1的位置发生改变,例如变到了,第二行第一列或者第一行第二列,可以将我上述的方法做一个方向的转变,但如何用python的一个函数,只传入数字1的位置,就可以输出魔法矩阵?

isdkz 发表于 2023-5-13 19:41:02

可以通过以下代码实现:

def magic_square(num_pos):
    # 定义一个3x3的空矩阵
    matrix = [ for j in range(3)]
    # 将数字1填入指定位置
    matrix]] = 1
    # 定义初始位置为数字1的位置
    row, col = num_pos, num_pos
    # 定义初始数字为2
    num = 2
    # 从数字2开始,依次填充矩阵
    while num <= 9:
      # 向右上方移动一格
      row -= 1
      col += 1
      # 如果移动后位置越界,回到原位置向下移动一格
      if row < 0 and col > 2:
            row += 2
            col -= 1
      # 如果移动后位置越界,回到原位置向上移动一格
      elif row < 0:
            row = 2
      # 如果移动后位置越界,回到原位置向右移动一格
      elif col > 2:
            col = 0
      # 如果移动后位置已经被填充,回到原位置向下移动一格
      elif matrix != 0:
            row += 2
            col -= 1
      # 在新位置填入数字
      matrix = num
      # 更新数字
      num += 1
    # 打印矩阵
    for i in range(3):
      for j in range(3):
            print(matrix[ i], end=' ')
      print()

# 测试
magic_square((2, 1))# 数字1在第三行第二列
magic_square((1, 0))# 数字1在第二行第一列
magic_square((0, 1))# 数字1在第一行第二列


该函数的实现思路是,先将数字1填入指定位置,然后从数字2开始,依次向右上方移动一格,如果移动后位置越界或已经被填充,则回到原位置向下移动一格。最终填充完毕后,打印出矩阵即可。

wanglyndon 发表于 2023-5-13 19:41:38

不知道表述的清楚不清楚.

陶远航 发表于 2023-5-13 19:43:19

要用Python编写一个函数,只传入数字1的位置,就可以输出和为15的魔法矩阵,可以按照以下步骤进行操作:

定义一个函数magic_square,并传入参数r、c,表示数字1的行、列坐标。

创建一个3 x 3的列表matrix,其中所有元素先初始化为0,用于存储魔法矩阵。

根据第一步的说明,从数字1的位置开始填充魔法矩阵。具体实现方式如下:

a. 将数字1填入指定位置。

b. 对于数字2~9,依次按照以下顺序填入矩阵中:
i. 如果该数字的右上角为空,则将该数字填入右上角;
ii. 否则将该数字填入当前位置的正下方;
iii. 如果当前位置在第三行第一列的位置,则其下方所对应的位置是第一行第三列,因此需要将该数字填入第一行第三列的位置。

判断魔法矩阵的各行、各列以及两个对角线之和是否都等于15,如果符合要求就输出矩阵,否则输出错误提示信息。

下面是完整代码:
def magic_square(r, c):
    matrix = [ for j in range(3)]# 初始化3x3的矩阵
    matrix = 1# 将数字1填入指定位置

    for num in range(2, 10):# 填写数字2到9
      nr, nc = (r - 1) % 3, (c + 1) % 3# 计算右上角的坐标
      if matrix == 0:# 如果右上角为空,则将数字填入右上角
            r, c = nr, nc
      else:
            r, c = (r + 1) % 3, c# 否则将数字填入当前位置的正下方
            if r == 0 and c == 0:# 但如果当前位置在第三行第一列位置,则需要填入第一行第三列
                r = 1

      matrix = num# 填入数字

    # 判断矩阵的各行、各列以及两个对角线之和是否都等于15
    if sum(matrix) == sum(matrix) == sum(matrix) == \
            sum(row for row in matrix) == sum(row for row in matrix) == \
            sum(row for row in matrix) == matrix + matrix + matrix == \
            matrix + matrix + matrix == 15:

      for row in matrix:# 输出矩阵
            print(row)
    else:
      print("无法构造魔法矩阵!")

# 例子:数字1在第三行第二列位置
magic_square(2, 1)

输出结果为:




注意,该函数只能生成一种符合要求的魔法矩阵,如果想生成其他位置上的魔法矩阵,需要修改数字填写的顺序和规则。

wanglyndon 发表于 2023-5-13 19:43:43

你俩为什么这么快

陶远航 发表于 2023-5-13 19:45:06

wanglyndon 发表于 2023-5-13 19:43
你俩为什么这么快

当然是打字快啊(

wanglyndon 发表于 2023-5-13 19:48:59

陶远航 发表于 2023-5-13 19:45
当然是打字快啊(

输出结果错的

wanglyndon 发表于 2023-5-13 19:51:14

isdkz 发表于 2023-5-13 19:41
可以通过以下代码实现:



不太对

sfqxx 发表于 2023-5-13 19:53:41

wanglyndon 发表于 2023-5-13 19:51
不太对

不,他们用的是脚本和gpt

wanglyndon 发表于 2023-5-13 19:55:27

sfqxx 发表于 2023-5-13 19:53
不,他们用的是脚本和gpt

看出来了,我刚刚用了gpt4都没给我生成明白

isdkz 发表于 2023-5-13 19:55:56

你可以使用以下的Python函数实现你的需求。这个函数将数字1的位置作为输入,然后生成一个满足所有行、列和对角线之和都为15的3x3魔法矩阵。

def magic_square(start_pos):
    # 初始化一个3x3的矩阵
    square = [*3 for _ in range(3)]
   
    # 定义移动规则
    move = [(1, 1), (-1, 0)]
    cur_pos = start_pos
    num = 1

    # 将数字从1到9填入矩阵中
    for _ in range(9):
      square]] = num
      next_pos = [(cur_pos+move) % 3 for i in range(2)]
      
      # 判断下一个位置是否已被填充
      if square]] != 0:
            next_pos = [(cur_pos+move) % 3 for i in range(2)]
      
      cur_pos = next_pos
      num += 1
   
    return square

# 测试函数
start_pos = (2, 1)# 1的位置在第三行第二列
square = magic_square(start_pos)

# 打印魔法矩阵
for row in square:
    print(row)


这个函数首先初始化一个3x3的零矩阵。然后,它定义了移动规则:默认的移动方向是向右上角移动,如果该位置已被填充,则向下移动。接着,函数将数字从1到9依次填入矩阵中。在填充每一个数字后,它都会根据移动规则更新当前位置。最后,函数返回生成的魔法矩阵。

这个函数假设你的输入是一个有效的起始位置,即在矩阵的范围内。如果输入的起始位置无效,函数可能会产生错误的结果或者出错。

wanglyndon 发表于 2023-5-13 20:00:42

isdkz 发表于 2023-5-13 19:55
你可以使用以下的Python函数实现你的需求。这个函数将数字1的位置作为输入,然后生成一个满足所有行、列和 ...

把1放在第二行第一列就错了

sfqxx 发表于 2023-5-13 20:11:53

可以使用回溯算法来解决这个问题。具体步骤如下:

定义一个3x3的数组来表示棋盘,初始值都为0。
从数字1开始,按照以下步骤依次填充棋盘:
如果当前格子没有填充数字,则尝试在该位置填充数字,
如果填充后不符合要求(即各行、各列以及两个对角线上的三个数之和不为15),则撤销该填充并尝试在下一个格子中填充数字。
如果最后一个数字填充成功,则输出结果。
填充数字的过程中,可以通过递归实现回溯,即先试探下一格,如果下一格填充失败,则回溯到当前格继续尝试其他数字。
下面是一个示例代码实现:
def solve_magic_square(board, num):
    # 定义停止条件
    if num > 9:
      return True

    # 计算当前num所处的行和列
    row = (num - 1) // 3
    col = (num - 1) % 3

    # 尝试在当前位置填充数字
    if board == 0:
      for value in range(1, 10):
            # 判断当前值是否合法
            if check_valid(board, row, col, value):
                board = value
                # 递归尝试下一个数字
                if solve_magic_square(board, num + 1):
                  return True
                # 如果下一个数字填充失败,回溯到当前格重新尝试其他数字
                board = 0
    else:
      # 如果当前位置已经填过数字,则直接递归尝试下一个数字
      if solve_magic_square(board, num + 1):
            return True

    return False

def check_valid(board, row, col, value):
    # 检查当前行和列的和
    if sum(board) + value > 15 or sum( for i in range(3)]) + value > 15:
      return False
    # 如果当前位置在对角线上,则检查另一条对角线的和
    if (row == col and sum( for i in range(3)]) + value > 15) \
            or (row == 2 - col and sum( for i in range(3)]) + value > 15):
      return False
    # 如果合法则返回True
    return True

def print_board(board):
    for row in board:
      print(row)

# 测试
board = [*3 for _ in range(3)]
solve_magic_square(board, 1)
print_board(board)
在上面的示例代码中,solve_magic_square()函数用于递归实现回溯算法,check_valid()函数用于判断填充数字后是否符合游戏规则,print_board()函数用于输出最终的结果。可以将数字1的位置作为函数的输入参数传进去,然后根据这个位置从数字1开始填充魔法矩阵。

liuhongrun2022 发表于 2023-5-14 10:18:10

wanglyndon 发表于 2023-5-13 19:43
你俩为什么这么快

他俩用的是chatgpt
页: [1]
查看完整版本: 有关矩阵列表。