题目:
编写一个程序,通过填充空格来解决数独问题。
数独的解法需 遵循如下规则:
数字 1-9 在每一行只能出现一次。
数字 1-9 在每一列只能出现一次。
数字 1-9 在每一个以粗实线分隔的 3x3 宫内只能出现一次。(请参考示例图)
数独部分空格内已填入了数字,空白格用 '.' 表示。
示例 1:
输入:board = [["5","3",".",".","7",".",".",".","."],["6",".",".","1","9","5",".",".","."],[".","9","8",".",".",".",".","6","."],["8",".",".",".","6",".",".",".","3"],["4",".",".","8",".","3",".",".","1"],["7",".",".",".","2",".",".",".","6"],[".","6",".",".",".",".","2","8","."],[".",".",".","4","1","9",".",".","5"],[".",".",".",".","8",".",".","7","9"]]
输出:[["5","3","4","6","7","8","9","1","2"],["6","7","2","1","9","5","3","4","8"],["1","9","8","3","4","2","5","6","7"],["8","5","9","7","6","1","4","2","3"],["4","2","6","8","5","3","7","9","1"],["7","1","3","9","2","4","8","5","6"],["9","6","1","5","3","7","2","8","4"],["2","8","7","4","1","9","6","3","5"],["3","4","5","2","8","6","1","7","9"]]
思路分析:
第一步,创建一个列表board,表示输入的初始数独题目。对于同一行,列表中创建一个列表。对于一个元素位置,也相应创建一个列表,原因是后序的加入可能取值达到相同格式。
第二步,筛选出可能元素,这里我分为3个循环,第一个循环同行,对于同行的元素加入到search2中。第二个循环同列,对于同列也是相同的处理方法。对于同一个方格的循环,先把空位置定位出他的方格,再转换循环他方格内部的元素,加入到search2中。这里注意,列表的特性是不允许出现相同的值,这里就得做一个小处理,判断此元素是否曾经出现在search2。循环完毕后,用search1(包含所有的可能取值)减去所有的search2得到search,再加入到原本的board中即可。
第三步,用已生成的board查询新产生的只有一个单位长度的元素,再去排除同行同列同方格的元素,多次循环,即可得到最终答案。
代码:
import pandas as pd
import numpy as np
#coding='utf-8'
board = [[[5],[3],[ ],[ ],[7],[ ],[ ],[ ],[ ]],
[[6],[ ],[ ],[1],[9],[5],[ ],[ ],[ ]],
[[ ],[9],[8],[ ],[ ],[ ],[ ],[6],[ ]],
[[8],[ ],[ ],[ ],[6],[ ],[ ],[ ],[3]],
[[4],[ ],[ ],[8],[ ],[3],[ ],[ ],[1]],
[[7],[ ],[ ],[ ],[2],[ ],[ ],[ ],[6]],
[[ ],[6],[ ],[ ],[ ],[ ],[2],[8],[ ]],
[[ ],[ ],[ ],[4],[1],[9],[ ],[ ],[5]],
[[ ],[ ],[ ],[ ],[8],[ ],[ ],[7],[9]]
]
def shuchu(board):
for i in range(9):
print()
for j in range(9):
print(board[i][j],end=' ')
print()
shuchu(board) #查看输入是否正确
def chazhao(board):
for i in range(9):
for j in range(9):
if len(board[i][j])!=1:
search = []
search1 = [1,2,3,4,5,6,7,8,9]
search2 = []
for a in range(9):#循环列
if a!=j:#不能等于同列
if len(board[i][a])==1:
search2.append(board[i][a][0])
for b in range(9):#循环行
if b!=i:
if len(board[b][j])==1:
search2.append(board[b][j][0])
I = int(i/3)*3
J = int(j/3)*3
for c in range(I,I+3):#循环同个单元格 不能有重复值
for d in range(J,J+3):
if c!=i & d!=j:
if len(board[c][d])==1:
if board[c][d] not in search2:
search2.append(board[c][d][0])
search = set(search1)-set(search2)
search = list(search)
board[i][j] = search
return board
def main(board):
for i in range(9):
for j in range(9):
if len(board[i][j])==0:
board = chazhao(board)
shuchu(board)
for i in range(9):
for j in range(9):
board = chazhao(board)
shuchu(board)
main(board)
题目分析:
此题目有一个很大的漏洞,若在第三步循环时候,得到的值不是长度为1的,那么就得需要挨个尝试值,若不满足采用回溯算法得出结果,代码中没有体现此分析的代码。