赞
踩
对于一棵多叉树,我们可以通过 “左孩子右兄弟” 表示法,将其转化成一棵二叉树。
如果我们认为每个结点的子结点是无序的,那么得到的二叉树可能不唯一。
换句话说,每个结点可以选任意子结点作为左孩子,并按任意顺序连接右兄弟。
给定一棵包含 N 个结点的多叉树,结点从 1 至 N 编号,其中 1 号结点是根,每个结点的父结点的编号比自己的编号小。
请你计算其通过 “左孩子右兄弟” 表示法转化成的二叉树,高度最高是多少。
注:只有根结点这一个结点的树高度为 0。
最开始还以为是数学规律,看题解发现是去深度遍历每个节点的深度。每一层的节点存储在一个数组里面,由于使用左孩子右兄弟的表示法,则最高的高 = 该节点的孩子节点个数 + 孩子节点中最高的深度
- import os
- import sys
- sys.setrecursionlimit(100000) #设置最深递归深度
- # 请在此输入您的代码
- N = int(input())
- nodes = [[] for i in range(N+1)]
- for i in range(2, N + 1): # 存储2 至 N 号结点的父结点编号
- j = int(input())
- nodes[j].append(i)
-
- def dfs(i):
- if nodes[i] is None: #该层节点为空 即没有深度 返回0
- return 0
-
- maxn = 0
- for j in nodes[i]:#遍历第i层子节点的深度
- maxn = max(maxn, dfs(j))
-
- deep = maxn
- return len(nodes[i]) + deep # 第i层的子节点(每一个子节点变成二叉树都是一层高度) + 子节点中最深的深度
-
- print(dfs(1))

小明冒充 X 星球的骑士,进入了一个奇怪的城堡。
城堡里边什么都没有,只有方形石头铺成的地面。
假设城堡地面是 n×n 个方格。如下图所示。
按习俗,骑士要从西北角走到东南角。可以横向或纵向移动,但不能斜着走,也不能跳跃。每走到一个新方格,就要向正北方和正西方各射一箭。(城堡的西墙和北墙内各有 n 个靶子)同一个方格只允许经过一次。但不必走完所有的方格。如果只给出靶子上箭的数目,你能推断出骑士的行走路线吗?有时是可以的,比如上图中的例子。
本题的要求就是已知箭靶数字,求骑士的行走路径(测试数据保证路径唯一)
使用dfs,多了一个判断西边和北边靶子上箭数目的条件。但是我还是不会写dfs,去查了题解,这个写得很清楚——>https://alex007.blog.csdn.net/article/details/90314923
有一个测试用例没有通过,超时了。
- import os
- import sys
-
- # 请在此输入您的代码
- def dfs(r, c):
- """
- Args:
- r: 当前搜索行
- c: 当前搜索列
- Returns: Bool值,表示是否找到了一条符合条件路径
- """
- if r == n - 1 and c == n - 1: # 到达右下角
- if sum(north_target) > 0 or sum(west_target) > 0: # 如果最后还有箭靶上面的数目不为零,也不符合要求
- return False
- path.append(r * n + c)
- print(' '.join(map(str, path)))
- return True
-
- path.append(r * n + c)
- direction = [(0, 1), (1, 0), (0, -1), (-1, 0)]
- for dr, dc in direction:
- nr, nc = r + dr, c + dc # 下一个搜索位置的行、列
-
- # 保证下一个搜索的位置符合要求
- if -1 < nr < n and -1 < nc < n and not visit[nr][nc] and north_target[nc] > 0 and west_target[nr] > 0:
- visit[nr][nc] = True
- north_target[nc] -= 1
- west_target[nr] -= 1
-
- if dfs(nr, nc):
- return True
- else: #该路径走不通 则撤销刚才的操作 标记该点未被访问 靶数分别+1 路径将该点删除
- visit[nr][nc] = False
- north_target[nc] += 1
- west_target[nr] += 1
-
- path.pop()
- return False
-
-
- if __name__ == '__main__':
- n = int(input())
- north_target = list(map(int, input().split()))
- west_target = list(map(int, input().split()))
-
- path = []
- visit = [[False] * n for _ in range(n)] # 标记该点是否被访问过
-
- visit[0][0] = True
- north_target[0] -= 1
- west_target[0] -= 1
- dfs(0, 0)

Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。