利用DFS的思维去解答,没有使用递归,使用的循环,通过empty和full两个列表存储已经填写的格子和没有填写的格子。代码如下:
class SudoKu:
def __init__(self, sudo):
self.sudo = sudo
self.empty = list(self.getEmptyCell()) # 存放空格子
self.full = [] # 存放已经填写的格子
def getEmptyCell(self):
for i in range(9):
for j in range(9):
if self.sudo[i][j] == 0:
yield [(i, j), 0]
def check(self, i, j, value): # 检查在i,j格子内是否可以填入value
if value in self.sudo[i]:
return False
if value in [self.sudo[i][j] for i in range(9)]:
return False
x, y = i // 3 * 3, j // 3 * 3
if value in [self.sudo[i][j] for i in range(x, x+3) for j in range(y, y+3)]:
return False
return True
def run(self):
while self.empty:
(x, y), v = self.empty.pop(0)
for i in range(v+1, 10): # 依次填入1~10的数字
if self.check(x, y, i):
self.full.append([(x, y), i])
self.sudo[x][y] = i
break
else: # 如果没有填入任何数字,说明单元格不可填,那么将上一个单元格从full中回溯到empty
self.empty.insert(0, [(x, y), 0])
(x, y), v = self.full.pop()
self.sudo[x][y] = 0 # 格子一定要重置,否则check函数检查会出问题
self.empty.insert(0, [(x, y), v])
self.show()
def show(self):
for row in self.sudo:
print(*row, sep=' ')
while True:
try:
data = [list(map(int, input().split())) for _ in range(9)]
SudoKu(data).run()
except EOFError: break 
京公网安备 11010502036488号