原文参见https://blog.csdn.net/qsgctysj/article/details/107095586 在确立解题思路前,重点对零点可填数字的个数进行量化分析,绘制折线图。
import matplotlib.pyplot as plt sdk = [0, 0, 5, 3, 0, 0, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 2, 0, 0, 7, 0, 0, 1, 0, 5, 0, 0, 4, 0, 0, 0, 0, 5, 3, 0, 0, 0, 1, 0, 0, 7, 0, 0, 0, 6, 0, 0, 3, 2, 0, 0, 0, 8, 0, 0, 6, 0, 5, 0, 0, 0, 0, 9, 0, 0, 4, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 9, 7, 0, 0, ] def logic_decision(y, x, k): # Line judgment if k in sdk[y * 9:y * 9 + 9] + sdk[x:73 + x:9]: return False # Column judgment if k in sdk[y * 9:y * 9 + 9] + sdk[x:73 + x:9]: return False # Block judgment head = y // 3 * 3 * 9 + x // 3 * 3 if k in sdk[head:head + 3] + sdk[head + 9:head + 12] + sdk[head + 18:head + 21]: return False return True def count_zero_point(): # Put zero in a list p_value = [] for y in range(9): for x in range(9): if sdk[y * 9 + x] == 0: avail = 0 for j in range(1, 10): if logic_decision(y, x, j): avail += 1 p_value.append(avail) else: p_value.append(0) return p_value point_value = count_zero_point() plt.figure(figsize=(15, 6), dpi=80) plt.plot(point_value) plt.xticks(range(0, 81, 9)) plt.show()图例说明:横坐标是数独从上至下,从左至右各点的序号,纵坐标是各点可填数字的个数,为0说明该点是非零点,无需填充。纵坐标越小(不含0),说明可填数越少,纵坐标越大,说明可填数越多。破解从最少可填数的点开始,效率会大大提升。每次动态调整后,依然按上述规则进行破解。在有多个最少可填数的点情况下,找到其中距上一个破解点的步长最短的点进行破解,这样做的好处是,可以让周边那些可填数较少的点的可填数加速减少,进一步提升破解效率。
