这是一个深度优先搜索DFS题目。
原题连接:2488 -- A Knight's Journey
参考资料:POJ 2488 - A Knight's Journey | 眈眈探求
参考资料:POJ2488-A Knight's Journey【骑士游历】_ζёСяêτ - 小優YoU-CSDN博客
参考资料:POJ-2488-A Knight's Journey_fuerbosi-CSDN博客
一 问题描述
骑士按照象棋中“马走日”的原则在棋盘行走,直到不重复地走完整个棋盘,并且输出“字典顺序最小”的一种路径。
已知棋盘的行列分别按数字和字母排序,为了获得“字典顺序最小”的输出路径,那么,起始点为“A1”,邻接点为其周围的8个点(为了保证字典顺序最小,这8个点的访问顺序如下图的序号1-8),其相对父节点的偏移量分别为:
dir = [[-1,-2],[1,-2],[-2,-1],[2,-1],[-2,1],[2,1],[-1,2],[1,2]]
1. 重点在于DFS的递归环节:需要清除不满足要求的父节点,并返回至上次迭代。
二 代码实现:
# POJ 2488 - A Knight's Journey # 原题:http://poj.org/problem?id=2488 # https://exp-blog.com/algorithm/poj/poj2488-a-knights-journey/ # https://www.cnblogs.com/llhthinker/p/4924654.html # https://www.cnblogs.com/kindleheart/p/9296931.html ## 但凡涉及深度优先搜索,少不了使用递归 # 参考这个试试看:https://blog.csdn.net/iteye_8149/article/details/82369913?spm=1001.2101.3001.6650.1&utm_medium=distribute.pc_relevant.none-task-blog-2%7Edefault%7ECTRLIST%7Edefault-1.no_search_link&depth_1-utm_source=distribute.pc_relevant.none-task-blog-2%7Edefault%7ECTRLIST%7Edefault-1.no_search_link # 参考:https://blog.csdn.net/lyy289065406/article/details/6647666 import collections ## 创建一个类,可能要用到: class Solution: def DFS(self,D_r,A_c): # 设置标志位 # self.falg = 0 # # self.steps = 1 # self.visited = set() self.visited.add(str(0)+";"+str(0)) # # 定义字典,存放节点和步数 # self.queue_dict = collections.defaultdict(list) # 定义 # self.dfs(0,0,0) return 0 def dfs(self,x,y,steps): if steps == A_c * D_r: # self.falg = 1 return True # self.queue_dict[steps] = [x,y] queue_dict[steps] = [x, y] self.visited.add(str(x) + ";" + str(y)) # 获得当前位置的8个邻接点,依次对每个邻接点执行深度优先搜索 for i in range(8): # 这8个邻接点,按照字典顺序进行搜索,这样可以保证首先查得的路径即为按字典顺序排列的路径 new_x = dir[i][0] + x new_y = dir[i][1] + y if (0<=new_x<=D_r-1 and 0<=new_y<=A_c) and (str(new_x) +";"+str(new_y)) not in self.visited: if self.dfs(new_x,new_y,steps+1): return True self.visited.remove((str(x) +";"+str(y))) # 能执行到这步,说明前面跳的8步都不符合要求 return False #即当前位置是错误位置,擦除记录返回上一步 ## 首先,接收输入 # 数据共计n组 n = int(input().strip()) # 存储接收到的n组数据 data = [] for i in range(n): R,C = map(int,input().strip().split(' ')) data.append([R,C]) print(data) ## 接下来,设计搜索 # 定义字典,存放节点和步数 queue_dict = collections.defaultdict(list) # 定义邻接点的搜寻顺序,按照字典顺序进行搜寻 dir = [[-1,-2],[1,-2],[-2,-1],[2,-1],[-2,1],[2,1],[-1,2],[1,2]] for i in range(n): # 分别处理每一组数据 D_r,A_c = data[i][0],data[i][1] # 设置标志位 test = Solution() test.DFS(D_r,A_c) if len(queue_dict)== D_r*A_c: print("Scenario #"+str(i+1)+":") res = '' for j in range(len(queue_dict)): res += chr(queue_dict[j][1]+ord('A')) + str(queue_dict[j][0]+1) print(res) if i!=n-1: print() else: print("Scenario #" + str(i+1) + ":") print("impossible") if i!=n-1: print()
输入:
3 1 1 2 3 4 3
输出:
Scenario #1: A1 Scenario #2: impossible Scenario #3: A1B3C1A2B4C2A3B1C3A4B2C4