[ 题解 ] [ 带记录的DFS/BFS ] 洛谷 P1028 数的计算
https://www.luogu.org/problemnew/show/P1028
题意:对于一个数N,它有 N/2 个子节点;每个子节点同样有 N/2 个子节点。
问一共多少节点。
这里以带记录的 DFS/BFS 做法来做题。
以9为例,直接上图:
9有4个子节点,4有2个子节点,这是很明显的。注意这其中:
1出现了5次,2出现了2次。
你大概也能猜出来,当 N 非常大时,会有很多重复的子节点,而这些子树都是相同的。
所以出于效率考虑,这里要记录每个子树的大小,之后就不需要重复计算。
只需在 DFS/BFS 的过程中把答案记录在数组中即可。
Ruby实现:
1 #coding=utf-8 2 ## ↑并没有什么卵用 3 4 ## 初始化数组,定义N=1,2,3的答案 5 arr = [-2, 1, 2, 2] + Array.new(997,-1) 6 ## arr[n]存的是对于n这个子树的大小 7 8 def func (num, arr=[]) 9 ## num本身就是子树的一个节点 10 sum = 1 11 12 ## 下一层有 num/2 个 13 for i in 1..num/2 14 if arr[i] > 0 15 sum += arr[i] ## 子树大小已知时直接取用 16 else 17 arr[i] = func i, arr 18 sum += arr[i] ## 否则计算答案并记录 19 end 20 end 21 arr[num] = sum ## 记录num子树大小并返回 22 end 23 24 ## 输入N 25 N = gets.to_i 26 27 ## 以N为入口开始调用方法 28 func N, arr 29 30 ## 结果被记录在arr[N] 31 puts arr[N] 32 33 ## 查看数组 34 =begin 35 for i in 1..N 36 print "#{arr[i]}," 37 end 38 puts "" 39 =end