题解 | #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里面找)。

全部评论

相关推荐

勇敢的联想人前程似锦:如果我是你,身体素质好我会去参军,然后走士兵计划考研211只需要200多分。
点赞 评论 收藏
分享
评论
1
收藏
分享
牛客网
牛客企业服务