首页 > 其他分享 >HJ44 Sudoku 数独 ”思维 搜索“

HJ44 Sudoku 数独 ”思维 搜索“

时间:2023-05-04 19:44:26浏览次数:43  
标签:Sudoku 矩阵 range renew 3x3 HJ44 get0 数独 row

数独要求:在横、竖、3x3矩阵内0-9不可重复出现

重点思路实现方法是,填入一个数后下一步推算基于前面已经填好的数值的新矩阵。
相当于在这一过程中不断更新初始值用于下一步计算。

递归穷举,从第一个空开始填;再更新矩阵填下一个值,一直到最后一个空填完。

回溯:

查错花最多时间在:回溯没重置0导致错误。“递归要缩小规模,回溯要重置或父节点...”
尝试错误需要回溯,回复需要有一个父亲指标,(从链表通过父亲节点回溯中得到启发)

 1 '''
 2 测试案例
 3 m=[[0, 9, 2, 0, 0, 1, 7, 6, 3],
 4 [0, 0, 3, 7, 6, 2, 9, 8, 5],
 5 [0, 0, 7, 3, 5, 9, 4, 1, 2],
 6 [6, 2, 4, 1, 9, 5, 3, 7, 8],
 7 [7, 5, 9, 8, 4, 3, 1, 2, 6],
 8 [1, 3, 8, 6, 2, 7, 5, 9, 4],
 9 [2, 7, 1, 5, 3, 8, 6, 4, 9],
10 [3, 8, 6, 9, 1, 4, 2, 5, 7],
11 [0, 0, 5, 2, 7, 6, 8, 3, 1]]
12 m=[[0, 9, 5, 0, 2, 0, 0, 6, 0],
13 [0, 0, 7, 1, 0, 3, 9, 0, 2],
14 [6, 0, 0, 0, 0, 5, 3, 0, 4],
15 [0, 4, 0, 0, 1, 0, 6, 0, 7],
16 [5, 0, 0, 2, 0, 7, 0, 0, 9],
17 [7, 0, 3, 0, 9, 0, 0, 2, 0],
18 [0, 0, 9, 8, 0, 0, 0, 0, 6],
19 [8, 0, 6, 3, 0, 2, 1, 0, 5],
20 [0, 5, 0, 0, 7, 0, 2, 8, 3]]
21 '''
22 m=[]
23 for i in range(9):    
24     m.append(list(map(int,input().split())))
25 
26 def renew(item):#判断i所在的3x3矩阵并返回矩阵值;
27     #第一个3x3矩阵每个元素下标除以3向下取整为0,第二个3x3矩阵横坐标取整为0,纵坐标为1;
28     #第三个3x3矩阵横坐标取整为0,纵坐标为2;第四个3x3矩阵横坐标取整为1,纵坐标为0,继续类推。
29     renew_grid=[m[i][j] for i in range(item[0]//3*3,item[0]//3*3+3) \
30                 for j in range(item[1]//3*3,item[1]//3*3+3)]
31     renew_row=m[item[0]]
32     mTranspose=list(zip(*m))
33     renew_col=mTranspose[item[1]]        
34     return renew_grid,renew_row,renew_col
35 def recursion(get0):
36     if not get0:
37         return True
38     renew_grid,renew_row,renew_col=renew(get0[0])
39     for j in range(1,10):
40 '''
41         if m[0][7]==6:
42             print(j,get0[0])
43             for i in m:    
44                 print(" ".join(map(str,i)))
45 '''
46         if j not in renew_grid and j not in renew_row and j not in renew_col:
47             m[get0[0][0]][get0[0][1]] =j #更新m矩阵的值 
48             if recursion(get0[1:]):#get0路径跟踪,顺利就去除第一个元素继续跟着
49                 return True     
50             else:
51                 m[get0[0][0]][get0[0][1]] =0#回溯要重置0,否则不可实现
52 get0=[]
53 for i in range(len(m)) :
54     for j in range(len(m[0])):
55         if m[i][j]==0:
56             get0.append((i,j))
57 renew_grid,renew_row,renew_col=renew(get0[0])
58 recursion(get0)
59 for i in m:    
60     print(" ".join(map(str,i)))

 代码行数优化

可把上述代码的renew函数通过下面优化,得到正在填充节点的行列和3x3矩阵。通过“”set()-“”技巧

1 def value(m, x, y):    
2     i, j = x//3, y//3    
3     grid = [m[i*3+r][j*3+c] for r in range(3) for c in range(3)]
4     row_val = m[x]
5     col_val = list(zip(*m))[y]    
6     val = set([i for i in range(1,10)]) - set(grid) - set(row_val) - set(col_val)
7     return list(val)

 

标签:Sudoku,矩阵,range,renew,3x3,HJ44,get0,数独,row
From: https://www.cnblogs.com/tanyuanqing/p/17372302.html

相关文章

  • #yyds干货盘点# LeetCode程序员面试金典:解数独
    题目:编写一个程序,通过填充空格来解决数独问题。数独的解法需遵循如下规则:数字 1-9 在每一行只能出现一次。数字 1-9 在每一列只能出现一次。数字 1-9 在每一个以粗实线分隔的 3x3 宫内只能出现一次。(请参考示例图)数独部分空格内已填入了数字,空白格用 '.' 表示。 示例1......
  • 37. 解数独
    编写一个程序,通过填充空格来解决数独问题。数独的解法需遵循如下规则:数字1-9在每一行只能出现一次。数字1-9在每一列只能出现一次。数字1-9在每一个以粗实线分隔的3x3宫内只能出现一次。(请参考示例图)数独部分空格内已填入了数字,空白格用'.'表示。>我的解法cla......
  • 有关数独问题的解决方法- Java实现
    直接法和位运算发1publicbooleanisValidSudoku(char[][]board){2int[][]line=newint[board.length][board.length];3int[][]colum=newint[board.length][board.length];4int[][]cell=newint[board.length][board.length];5for(inti=......
  • P1074 [NOIP2009 提高组] 靶形数独
    题目传送门思路就是一个填数独的小游戏不会填数独的先去自己玩几把众所周知,数独每一行、每一列、每一个3*3宫格内的数字均含1~9,且不重复所以我们设三个数组r[10][10],c[10][10],block[10][10]分别记录行、列、3*3宫格内数字的使用情况重点:剪枝我们知道,数独的玩法是先从已知......
  • 解数独 【笔试题】
    本题虽然是困难但是难度不大写的时候也是有经验classSolution{publicvoidsolveSudoku(char[][]board){backtrack(board,0,0);}public......
  • 【leetcode-数组】有效的数独
    判断一个 9x9的数独是否有效。只需要根据以下规则,验证已经填入的数字是否有效即可。数字 1-9 在每一行只能出现一次。数字 1-9 在每一列只能出现一次。数字 1-9 在......
  • 【LeetCode回溯算法#11】解数独,这次是真的用回溯法处理二维数组
    解数独力扣题目链接(opensnewwindow)编写一个程序,通过填充空格来解决数独问题。一个数独的解法需遵循如下规则:数字1-9在每一行只能出现一次。数字1-9在每一列只......
  • #yyds干货盘点# LeetCode面试题:解数独
    1.简述:编写一个程序,通过填充空格来解决数独问题。数独的解法需遵循如下规则:数字 1-9 在每一行只能出现一次。数字 1-9 在每一列只能出现一次。数字 1-9 在每一个以粗......
  • 算法随想Day27【回溯算法】| LC332-重新安排行程、LC51-N皇后、LC37-解数独
    LC332.重新安排行程做了很久,还是没有通过全部案例,最后是一个输入为100个元素的数组,运行超出时间限制。LC51.N皇后实现了回溯算法中的超暴力解法,主要是对某个节点的斜......
  • 代码随想录算法训练营Day30 回溯算法| 332.重新安排行程 51. N皇后 37. 解数独 总结
    代码随想录算法训练营332.重新安排行程题目链接:332.重新安排行程给定一个机票的字符串二维数组[from,to],子数组中的两个成员分别表示飞机出发和降落的机场地点,对该行......