题解 | #Sudoku#
Sudoku
https://www.nowcoder.com/practice/78a1a4ebe8a34c93aac006c44f6bf8a1
def find0(ls): res = [] for i in range(9): for j in range(9): if ls[i][j]==0: pos = [i,j] res.append([pos,find_vacancy(pos,ls)]) return res def find_vacancy(pos,ls): i = pos[0] j = pos[1] row = ls[i] cross = [line[j] for line in ls] i = i-i%3 j = j-j%3 squre = [] for line in ls[i:i+3]: squre += line[j:j+3] helper = list(set(row+cross+squre)) # print(helper) res = [] for item in range(1,10): if item not in helper: res.append(item) return res def clear_data(cur,ls): for i in range(len(cur)): vacancy = cur[i][1] relatives1 = set() relatives2 = set() relatives3 = set() temp1 = [] temp2 = [] temp3 = [] for j in range(len(cur)): if cur[i][0][0] == cur[j][0][0]: for item in cur[j][1]: relatives1.add(item) elif cur[i][0][1] == cur[j][0][1]: for item in cur[j][1]: relatives2.add(item) if (cur[i][0][1]//3 == cur[j][0][1]//3 and cur[i][0][1]//3 == cur[j][0][1]//3): for item in cur[j][1]: relatives3.add(item) for item in vacancy: if item not in relatives1: temp1.append(item) if item not in relatives2: temp2.append(item) if item not in relatives2: temp3.append(item) # temp = temp1&temp2&temp3 if len(temp1) == 1: cur[i][1] = temp1 break if len(temp2) == 1: cur[i][1] = temp2 break if len(temp3) == 1: cur[i][1] = temp3 break ls = [] for i in range(9): ls.append(list(map(int,input().split()))) while True: cur = sorted(find0(ls),key = lambda x:len(x[1])) # print(cur) if len(cur)==0: break if len(cur[0][1]) != 1: # print(cur) clear_data(cur,ls) cur = sorted(cur,key = lambda x:len(x[1])) # print(cur) ls[cur[0][0][0]][cur[0][0][1]] = cur[0][1][0] cur = cur[1:] continue while len(cur)!=0 and len(cur[0][1]) == 1: ls[cur[0][0][0]][cur[0][0][1]] = cur[0][1][0] cur = cur[1:] for i in range(9): for j in range(9): print(ls[i][j],end=' ') print()
一上来没有考虑遍历,想着按照我做数独的顺序,先把每个空可以填的值找出来,按可选值数量排好序,对于只有一个可选值的直接填上,没有唯一可选值之后更新数独循环,当出现多个可选值时,与该格相关的行、列、3*3分别判断,比如:[0,1] [0,2] [0,3] 可填只有 4,5,6,而在第2列、第3列分别都有4,所以4只能填在[0,1]的位置,没有从最开始确定可选值的时候就用上这个函数因为计算量比较大容易超(用字典尝试先把空格分好组可能会好些)。
效率惨不忍睹,每个格子信息写成一个类可能会清晰很多,三个函数第一个是找到所有0,第二个是找到每个0对应的能够填的未被占用的值,第三个函数为找到必须填的值(分别从行、列、3*3里面找)。