问题描述:
将n*n数字棋盘空缺位置补齐,使得所有数字按顺序经过所有格子并连成一条曲线,相邻两点之间可通过上下左右和对角线共8种方式连接。
比如下面是试题题面:
解决算法:
维护一个candidate集合,里面元素表示与当前题面上所存在数字相邻的数字。整体算法使用深度优先搜索,每次在candidate集合中取出一个元素,然后获取可放置位置,遍历有效位置进行递归求解。递归出口:candidate集合为空。
python代码:
class Matrix:
def __init__(self, grid):
self.n = len(grid)
self.grid = grid
self.visited = [[0 for j in range(self.n)] for i in range(self.n)]
self.number = {}
self.candi = set()
def build(self):
for i in range(self.n):
for j in range(self.n):
if self.grid[i][j]!=0:
self.number[self.grid[i][j]] = (i, j)
self.visited[i][j] = 1
for num in self.number:
if num - 1 not in self.number and num!=1:
self.candi.add(num-1)
if num + 1 not in self.number and num!=self.n*self.n:
self.candi.add(num+1)
self.opts = [(-1, 0), (1, 0), (0, -1), (0, 1), (-1, -1), (-1, 1), (1, 1), (1, -1)]
def run_model(self):
self.build()
f = self.solve()
for i in range(1, self.n*self.n+1):
x, y = self.number[i]
self.grid[x][y] = i
def get_candi_position(self, key):
res = set()
x, y = self.number[key]
for op in self.opts:
nx ,ny = x+op[0], y+op[1]
if nx>=0 and nx<self.n and ny>=0 and ny<self.n and self.visited[nx][ny]==0:
res.add((nx, ny))
return res
def solve(self):
if not self.candi:
return True
item = list(self.candi)[-1]
self.candi.remove(item)
adj_position = set()
nei1 = set()
nei2 = set()
if item + 1 in self.number:
nei1 = self.get_candi_position(item+1)
if item - 1 in self.number:
nei2 = self.get_candi_position(item-1)
if item + 1 in self.number and item - 1 in self.number:
adj_position = nei1.intersection(nei2)
elif item + 1 in self.number:
adj_position = nei1
elif item - 1 in self.number:
adj_position = nei2
for x, y in adj_position:
self.number[item] = (x, y)
self.visited[x][y] = 1
n1 = False
n2 = False
if item + 1 not in self.number and item+1<=self.n*self.n:
if item+1 not in self.candi:
self.candi.add(item+1)
n1 = True
if item - 1 not in self.number and item-1>=1:
if item-1 not in self.candi:
self.candi.add(item-1)
n2 = True
if self.solve():
return True
del self.number[item]
self.visited[x][y] = 0
if n1:
self.candi.remove(item+1)
if n2:
self.candi.remove(item-1)
self.candi.add(item)
return False
def __str__(self):
s = []
for i in range(self.n):
s_t = ""
for j in range(self.n):
s_t += "{:<5}".format(self.grid[i][j])
s_t += "\n"
s.append(s_t)
return "\n".join(s)
grid = [[35,36,0,0,0,49,0],[0,0,39,0,41,0,0],[30,0,0,27,0,0,46],[0,0,1,0,0,23,0],[0,4,0,0,24,0,0],[0,0,0,12,15,0,19],[7,8,0,0,0,0,18]]
m = Matrix(grid)
m.run_model()
print(m)
运行结果:
在最强大脑app填入答案:
成绩排在第9,时间2:19。时间主要消耗在输入输出题面。