题解 | #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宫格的可能值,然后在每一个元素上针对索引取并集