解数独题,没有用class实例化点,也没有用递归,写的有点乱,有些地方还可以精简,不过测试效果还不错,这最难数独只用了0.8s,不过我电脑比较好,在其他电脑上尝试有1.4秒多的,在Ipad mini的pythonista上要跑2.4秒左右。其他的数独题没有测试,应该会时间更短。
我的解题思路比较暴力,先尝试最右下角一个数字(因为这里其他数字多一些,空白可能的数字少,节约了很多计算),最先填进去最小的数字,如果可以填下就去尝试下一个数字,如果没有合法数字,就返回上一个数字,让上一个数字加1后继续判断合法性。直到所有数字都能填下。
在尝试的数字已经是可以填进去的最大值的时候,也会进检测函数监测数字的合法性,这里如果加上个判断,能少一些调用check,还能提升些许的效率。
import time
t=time.time()
a=[
8,0,0,0,0,0,0,0,0,
0,0,3,6,0,0,0,0,0,
0,7,0,0,9,0,2,0,0,
0,5,0,0,0,7,0,0,0,
0,0,0,0,4,5,7,0,0,
0,0,0,1,0,0,0,3,0,
0,0,1,0,0,0,0,6,8,
0,0,8,5,0,0,0,1,0,
0,9,0,0,0,0,4,0,0]
#定位已经有数字的位置
have_num=[]
for i in range(len(a)):
if a[i] !=0:
have_num.append(i)
#获取目前位置的坐标,获取9宫格内不同的数字
def number(i):
x,y,b,c,d,e=0,0,0,0,0,0
y1=i//9
x1=i%9
y=i//9%3
x=i%9%3
if x==0 and y==0:
b,c,d,e=i+10,i+11,i+19,i+20
elif x==0 and y==1:
b,c,d,e=i-8,i+10,i-7,i+11
elif x==0 and y==2:
b,c,d,e=i-8,i-7,i-17,i-16
elif x==1 and y==0:
b,c,d,e=i+8,i+10,i+19,i+17
elif x==1 and y==1:
b,c,d,e=i+10,i-8,i+8,i-10
elif x==1 and y==2:
b,c,d,e=i-8,i-10,i-19,i-17
elif x==2 and y==0:
b,c,d,e=i+7,i+8,i+17,i+16
elif x==2 and y==1:
b,c,d,e=i+8,i-10,i+7,i-11
elif x==2 and y==2:
b,c,d,e=i-10,i-11,i-19,i-20
return x1,y1,b,c,d,e
#进行主要逻辑,对第i个数字进行检测合法性,不合法则加一后再监测
#检测完没有合法的数字返回错误
count=0
def check(i):
global count
count=count+1
temp=a[i]
x,y,b,c,d,e=number(i)
x_lable=a[y*9:y*9+9]
y_lable=[]
for i in range(x,81,9):
y_lable.append(a[i])
kong_lable=[a[b],a[c],a[d],a[e]]
del(x_lable[x])
del(y_lable[y])
lable=set(x_lable+y_lable+kong_lable)
while 1:
if temp in lable:
temp=temp+1
else:
break
if temp==10:
return 0
else:
return temp
#主框架,主逻辑返回错误则监测位置返回上一个监测位置,加一后继续监测。
i=80
while i>=0:
if i in have_num:
i=i-1
else:
a[i]=a[i]+1
a[i]=check(i)
if a[i] !=0:
i=i-1
else:
i=i+1
while i in have_num:
i=i+1
#打印
for i in range(1,82):
print('[%d]'%a[i-1],end='')
if i%9==0:
print('')
t2=time.time()
print(t2-t,count)