题解 | #Sudoku#
Sudoku
https://www.nowcoder.com/practice/78a1a4ebe8a34c93aac006c44f6bf8a1
def getAbs(sudoku_sqr):
all_num = set([i for i in range(1, 10)])
line_abs = []
for i in range(9):
line_num = set(sudoku_sqr[i])-set([0])
line_abs.append(all_num - line_num)
col_abs = []
for i in range(9):
col_num = set([sudoku_sqr[j][i] for j in range(9)])-set([0])
col_abs.append(all_num - col_num)
win_abs = [[] for _ in range(3)]
for i in range(3):
for j in range(3):
win_num = set([sudoku_sqr[i*3][j*3], sudoku_sqr[i*3][j*3+1], sudoku_sqr[i*3][j*3+2],
sudoku_sqr[i*3+1][j*3], sudoku_sqr[i*3+1][j*3+1], sudoku_sqr[i*3+1][j*3+2],
sudoku_sqr[i*3+2][j*3], sudoku_sqr[i*3+2][j*3+1], sudoku_sqr[i*3+2][j*3+2]]) - set([0])
win_abs[i].append(all_num - win_num)
ele_abs = [[None for __ in range(9)] for _ in range(9)]
for i in range(9):
for j in range(9):
if not sudoku_sqr[i][j]:
ele_abs[i][j] = line_abs[i]&col_abs[j]&win_abs[i//3][j//3]
return ele_abs
def fillSqr(sudoku_sqr, absense):
for k in range(1, 10):
fillOcc = 0
for i in range(9):
for j in range(9):
if absense[i][j] and len(absense[i][j]) == k:
fillment = list(absense[i][j])[0]
sudoku_sqr[i][j] = fillment
fillOcc = 1
break
if fillOcc:
break
if fillOcc:
break
return sudoku_sqr
def finishedSudoku(sudoku_sqr):
for i in range(9):
for j in range(9):
if not sudoku_sqr[i][j]:
return False
return True
in_sudoku_sqr = []
for _ in range(9):
sudoku_line = list(map(int, input().split(' ')))
in_sudoku_sqr.append(sudoku_line)
while not finishedSudoku(in_sudoku_sqr):
abs_sqr = getAbs(in_sudoku_sqr)
in_sudoku_sqr = fillSqr(in_sudoku_sqr, abs_sqr)
for i in range(9):
for j in range(9):
print(in_sudoku_sqr[i][j], end=' ')
print('')
基本思路,统计每个空位的可能值,从可能值数量最小的开始填写,每次填写一个,就重新统计其他空位的可能值,直到所有空位填写完
统计每个空位的可能值时,不用暴力统计,只需要统计每行、每列、每个9宫格的可能值,然后在每一个元素上针对索引取并集
美的集团公司福利 747人发布