题解 | #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')