def find_min_steps(beginStr, endStr, strSet):
from collections import deque
# 初始化队列,将开始字符串加入队列
queue = deque([beginStr])
# 初始化访问字典,记录字符串到开始字符串的步数
visit_map = {beginStr: 1}
while queue:
word = queue.popleft()
path = visit_map[word]
# 对当前字符串的每个字符进行遍历
for i in range(len(word)):
# 遍历26个字母
for j in range(26):
# 替换当前字符
new_word = word[:i] + chr(ord('a') + j) + word[i + 1:]
# 如果新字符串与结束字符串相同
if new_word == endStr:
print(path + 1)
return
# 如果新字符串在集合中且未被访问过
if new_word in strSet and new_word not in visit_map:
# 记录新字符串的步数,并加入队列
visit_map[new_word] = path + 1
queue.append(new_word)
# 如果没有找到路径,输出0
print(0)
def main():
n = int(input().strip())
beginStr, endStr = input().strip().split()
strSet = set()
for _ in range(n):
strSet.add(input().strip())
find_min_steps(beginStr, endStr, strSet)
if __name__ == "__main__":
main()
-
使用
deque
(双端队列)作为队列实现,将开始字符串加入队列。 -
使用
visit_map
字典记录每个字符串到开始字符串的最短步数。 -
当队列不为空时,执行循环。每次从队列中取出一个字符串,并获取其对应的步数。
-
遍历当前字符串的每个字符,然后遍历26个字母,尝试用每个字母替换当前位置的字符,生成新的字符串
new_word
。 -
如果
new_word
与结束字符串endStr
相同,说明找到了最短路径,打印步数并结束函数。 -
如果
new_word
在字符串集合strSet
中且未被访问过(不在visit_map
中),则将其加入visit_map
并将其加入队列。 -
如果循环结束后没有找到路径,则打印0。
-
main
函数读取输入,初始化开始字符串、结束字符串和字符串集合strSet
。 -
调用
find_min_steps
函数执行搜索。
def dfs(graph, key, visited):
# 如果已经访问过该节点,则直接返回
if visited[key]:
return
visited[key] = True # 标记当前节点为已访问
# 遍历当前节点的所有邻接节点
for neighbor in graph[key]:
dfs(graph, neighbor, visited) # 递归地进行深度优先搜索
def main():
n, m = map(int, input().split())
graph = [list() for _ in range(n + 1)] # 使用列表的列表表示邻接表
while m:
s, t = map(int, input().split())
graph[s].append(t) # 构建图的邻接表,表示 s 到 t 的连接
m -= 1
visited = [False] * (n + 1) # 初始化访问记录列表
dfs(graph, 1, visited) # 从节点 1 开始深度优先搜索
# 检查是否所有节点都访问到了
if False in visited[1:]: # 从第二个元素开始检查,因为第一个元素默认为False
print(-1)
else:
print(1)
if __name__ == "__main__":
main()
-
dfs
函数是一个递归函数,用于执行深度优先搜索(DFS)。它接受邻接表graph
、当前节点key
和一个访问记录列表visited
。 -
如果当前节点已经被访问过(
visited[key]
为True
),则直接返回,这是DFS的剪枝操作,避免循环。 -
将当前节点标记为已访问,并遍历当前节点的所有邻接节点。
-
对每个邻接节点,递归调用
dfs
函数,继续深度优先搜索。 -
main
函数首先读取节点数n
和边数m
。 -
初始化邻接表
graph
,使用列表的列表结构表示,长度为n + 1
(因为节点编号从1开始)。 -
通过循环读取每条边的信息,并构建图的邻接表。
-
初始化访问记录列表
visited
,长度为n + 1
,所有元素初始为False
。 -
调用
dfs
函数,从节点 1 开始执行深度优先搜索。 -
搜索完成后,检查
visited
列表,如果存在未访问的节点(False
),则输出-1
表示图中有未被访问的节点;否则,输出1
表示所有节点都被访问到了。
def main():
n, m = map(int, input().split()) # 读取行数和列数
grid = [] # 初始化网格列表
for _ in range(n):
grid.append(list(map(int, input().split()))) # 读取每行的陆地数据
sum_ = 0 # 陆地数量
cover = 0 # 相邻数量
for i in range(n): # 遍历每一行
for j in range(m): # 遍历每一列
if grid[i][j] == 1: # 检查当前位置是否是陆地
sum_ += 1 # 统计总的陆地数量
# 统计上边相邻陆地(避免越界)
if i - 1 >= 0 and grid[i - 1][j] == 1:
cover += 1
# 统计左边相邻陆地(避免越界)
if j - 1 >= 0 and grid[i][j - 1] == 1:
cover += 1
# 不需要统计下边和右边,因为每个格子的下边和右边将由下一行和下一列来统计
print(sum_ * 4 - cover * 2) # 计算并输出结果
if __name__ == "__main__":
main()
-
使用列表推导式和
map
函数读取每行的陆地数据,并将每行数据转换为整数列表。 -
初始化两个计数器
sum_
和cover
分别用于统计陆地数量和相邻陆地数量。 -
使用两层嵌套循环遍历整个网格,外层循环遍历行,内层循环遍历列。
-
如果当前位置是陆地(
grid[i][j] == 1
),则sum_
加一。 -
检查当前陆地的上边和左边是否有相邻的陆地,并更新
cover
计数器。这里只检查上边和左边,因为下边和右边的相邻陆地将由对应的下一行和下一列来检查,避免重复计算。 -
最后,计算并打印结果。每个陆地单元格理论上有四个边界,但由于每个边界会被相邻的单元格共享两次(一次由当前单元格统计,一次由相邻的单元格统计),所以实际的边界总数是
sum_ * 4 - cover * 2
。