题解 | #Sudoku#
Sudoku
https://www.nowcoder.com/practice/78a1a4ebe8a34c93aac006c44f6bf8a1
#凡是涉及到迭代的过程,一般都会在函数中嵌套本身。没有接触过的时候,需要逐步接受这种思维方式。
import sys
def isvalid(sudo,x,y):
#定义一个是否可填函数:判断数独sudo的(x,y)位置与其他关联位置(行列方格)是否冲突。
for i in range(9): #判断(x,y)与同列的位置是否冲突
if (i != x) and (sudo[i][y] == sudo[x][y]):
return False
for j in range(9): #判断(x,y)与同行的位置是否冲突
if (j != y) and (sudo[x][j] == sudo[x][y]):
return False
m = (x//3)*3 #3*3方格的行起点
n = (y//3)*3 #3*3方格的列起点
for i in range(3):
for j in range(3):
if ((m+i != x) or (n+j != y)) and sudo[m+i][n+j] == sudo[x][y]:
#判断(x,y)位置与自身所处3*3方格内的其他位置是是否冲突
return False
return True
def dfs(sudo):
#定义一个深度优先的函数,返回值为True/False。由于sudo是列表,在函数内进行操作可以改变其值。在搜索完成后,直接调用即可,无需返回。
for i in range(9):
for j in range(9):
if sudo[i][j] == 0:
#逐行列找到待填的位置
for k in '123456789':
sudo[i][j] = int(k) #先从1-9里填一个k
if isvalid(sudo,i,j) and dfs(sudo):
#如果填的k可用,则继续探索。
return True
sudo[i][j] = 0 #如果k都不可用则上一步填错了,把(i,j)位置重新归0
return False
return True
sudo = []
for i in range(9):
sudo.append(list(map(int,input().split())))
dfs(sudo)
sudo = [' '.join([str(_) for _ in x]) for x in sudo]
print(*(sudo),sep='\n')
