当前位置:   article > 正文

左孩子右兄弟&&路径之谜

左孩子右兄弟&&路径之谜

题目

对于一棵多叉树,我们可以通过 “左孩子右兄弟” 表示法,将其转化成一棵二叉树

如果我们认为每个结点的子结点是无序的,那么得到的二叉树可能不唯一。

换句话说,每个结点可以选任意子结点作为左孩子,并按任意顺序连接右兄弟。

给定一棵包含 N​​ 个结点的多叉树,结点从 1​​ 至 N​ 编号,其中 1 号结点是根,每个结点的父结点的编号比自己的编号小。

请你计算其通过 “左孩子右兄弟” 表示法转化成的二叉树,高度最高是多少。

注:只有根结点这一个结点的树高度为 0​。

思路

最开始还以为是数学规律,看题解发现是去深度遍历每个节点的深度。每一层的节点存储在一个数组里面,由于使用左孩子右兄弟的表示法,则最高的高 = 该节点的孩子节点个数 + 孩子节点中最高的深度 

代码

  1. import os
  2. import sys
  3. sys.setrecursionlimit(100000) #设置最深递归深度
  4. # 请在此输入您的代码
  5. N = int(input())
  6. nodes = [[] for i in range(N+1)]
  7. for i in range(2, N + 1): # 存储2​ 至 N 号结点的父结点编号
  8. j = int(input())
  9. nodes[j].append(i)
  10. def dfs(i):
  11. if nodes[i] is None: #该层节点为空 即没有深度 返回0
  12. return 0
  13. maxn = 0
  14. for j in nodes[i]:#遍历第i层子节点的深度
  15. maxn = max(maxn, dfs(j))
  16. deep = maxn
  17. return len(nodes[i]) + deep # 第i层的子节点(每一个子节点变成二叉树都是一层高度) + 子节点中最深的深度
  18. print(dfs(1))

题目

小明冒充 X 星球的骑士,进入了一个奇怪的城堡。

城堡里边什么都没有,只有方形石头铺成的地面。

假设城堡地面是 n×n 个方格。如下图所示。

 

按习俗,骑士要从西北角走到东南角。可以横向或纵向移动,但不能斜着走,也不能跳跃。每走到一个新方格,就要向正北方和正西方各射一箭。(城堡的西墙和北墙内各有 n 个靶子)同一个方格只允许经过一次。但不必走完所有的方格。如果只给出靶子上箭的数目,你能推断出骑士的行走路线吗?有时是可以的,比如上图中的例子。

本题的要求就是已知箭靶数字,求骑士的行走路径(测试数据保证路径唯一)

思路

 使用dfs,多了一个判断西边和北边靶子上箭数目的条件。但是我还是不会写dfs,去查了题解,这个写得很清楚——>https://alex007.blog.csdn.net/article/details/90314923​​​​​​

有一个测试用例没有通过,超时了。 

代码 

  1. import os
  2. import sys
  3. # 请在此输入您的代码
  4. def dfs(r, c):
  5. """
  6. Args:
  7. r: 当前搜索行
  8. c: 当前搜索列
  9. Returns: Bool值,表示是否找到了一条符合条件路径
  10. """
  11. if r == n - 1 and c == n - 1: # 到达右下角
  12. if sum(north_target) > 0 or sum(west_target) > 0: # 如果最后还有箭靶上面的数目不为零,也不符合要求
  13. return False
  14. path.append(r * n + c)
  15. print(' '.join(map(str, path)))
  16. return True
  17. path.append(r * n + c)
  18. direction = [(0, 1), (1, 0), (0, -1), (-1, 0)]
  19. for dr, dc in direction:
  20. nr, nc = r + dr, c + dc # 下一个搜索位置的行、列
  21. # 保证下一个搜索的位置符合要求
  22. if -1 < nr < n and -1 < nc < n and not visit[nr][nc] and north_target[nc] > 0 and west_target[nr] > 0:
  23. visit[nr][nc] = True
  24. north_target[nc] -= 1
  25. west_target[nr] -= 1
  26. if dfs(nr, nc):
  27. return True
  28. else: #该路径走不通 则撤销刚才的操作 标记该点未被访问 靶数分别+1 路径将该点删除
  29. visit[nr][nc] = False
  30. north_target[nc] += 1
  31. west_target[nr] += 1
  32. path.pop()
  33. return False
  34. if __name__ == '__main__':
  35. n = int(input())
  36. north_target = list(map(int, input().split()))
  37. west_target = list(map(int, input().split()))
  38. path = []
  39. visit = [[False] * n for _ in range(n)] # 标记该点是否被访问过
  40. visit[0][0] = True
  41. north_target[0] -= 1
  42. west_target[0] -= 1
  43. dfs(0, 0)
声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/Gausst松鼠会/article/detail/692771
推荐阅读
相关标签
  

闽ICP备14008679号