python DFS算法求解
修改于2022/01/14982 浏览攻略
没有人编程求解,那我来写一个吧(恼)
就是一个广度优先搜索,没什么特别的。先贴代码,有时间再补充点思路:
分割线------------------------------------------------------------------------------------
import copy
class Node:
def __init__(self, goal=1, size=0):
self.neighbors = []
self.goal = goal
self.size = size
def __str__(self):
return f'{self.goal}-{self.size}'
def enlarge(self):
if self.size < 2:
self.size += 1
def shrink(self):
if self.size > 0:
self.size -= 1
return True
return False
def click(self):
if self.shrink():
for n in self.neighbors:
n.enlarge()
def connect(self, other):
if other is not None:
if other not in self.neighbors: self.neighbors.append(other)
if self not in other.neighbors: other.neighbors.append(self)
def disconnect(self, other):
if other is not None:
if other in self.neighbors: self.neighbors.remove(other)
if self in other.neighbors: other.neighbors.remove(self)
def Y(size):
return Node(1,size)
def P(size):
return Node(0,size)
def B(size):
return Node(2,size)
class NodeMap:
def __init__(self, nodes):
self.nodes = nodes
def __str__(self):
if self.nodes is None or len(self.nodes) == 0: return ''
return '[' + ' '.join([x.__str__() for x in self.nodes]) + ']'
def get_hash(self):
ans = 0
for n in self.nodes:
ans *= 3
ans += n.size
return ans
def satisfy(self):
for n in self.nodes:
if n.goal != n.size:
return False
return True
def update(self, index):
if 0 <= index < len(self.nodes):
new_map = copy.deepcopy(self)
new_map.nodes[index].click()
return new_map
return None
def generate_map(list):
for i in range(len(list)-1):
for j in range(len(list[0])):
if list[j] is not None:
list[j].connect(list[i+1][j])
for i in range(len(list)):
for j in range(len(list[0])-1):
if list[j] is not None:
list[j].connect(list[j+1])
one_list = []
for l in list:
for ll in l:
if ll is not None:
one_list.append(ll)
return NodeMap(one_list)
def solve(node_map):
queue = []
hashes = set([])
queue.append((node_map, []))
hashes.add(node_map.get_hash())
while queue:
node_map, steps = queue.pop(0)
if node_map.satisfy():
return steps
for i in range(len(node_map.nodes)):
new_map = node_map.update(i)
new_hash = new_map.get_hash()
new_steps = steps.copy()
new_steps.append(i)
if new_hash not in hashes:
hashes.add(new_hash)
queue.append((new_map, new_steps))
分割线------------------------------------------------------------------------------------
代码使用方法是这样的,以第17关为例:
![TapTap](https://img2.tapimg.com/bbcode/images/43cf7e9cf21e78cbaa5f4d9c88205831.png?imageMogr2/thumbnail/1080x9999%3E/quality/80/format/jpg/interlace/1/ignore-error/1&t=1)
先把题目用二维矩阵表示出来,黄色方块是Y,蓝色是B,粉色是P。大方块是2,中等是1,小方块是0。如果没有方块,就填None。
接着调用generate_map把数组转化成NodeMap类型,再对其调用solve函数即可输出步骤列表。
写成代码是这样的:
分割线------------------------------------------------------------------------------------
nodes17 = [
[B(1), Y(0), B(1)],
[Y(0), Y(1), Y(0)],
[Y(1), None, Y(1)],
]
node_map = generate_map(nodes17)
print(solve(node_map))
分割线------------------------------------------------------------------------------------
每个方块都有一个编号,编号从零开始,从上往下,从左往右递增。输出列表是[6, 3, 7, 5, 4], 所以按照对应顺序点击即可~