已知最大深度为16的完整二叉树,所有叶节点的深度相同。如果在根节点上放置一个小球,则该球将开始沿根节点掉落。完整的二叉树中的每个节点上都有一个开关。默认为关闭。当球落下时,只要球落在开关上,开关的状态就会改变。当球到达某个节点时,如果该节点上的开关闭合,则向左转到该球,否则向右转到直到到达叶子节点。请帮助我找到第12345个球掉落后的叶子节点编号。
答案 0 :(得分:1)
您可以模拟一个给定的问题,并注意到在一个时间点之后,球末端的叶子节点趋向于重复自身。例如,对于深度为3的二叉树,多个滚动球的球结束处的叶节点为1 3 2 4 1 3 2 4 1 3 2 4 . . .
(假设叶节点的编号从1 开始)。可见,长度2 3-1 = 4的序列不断重复。我们可以将该序列存储在数组中,并通过查找与 n mod 2 depth-1 <相对应的条目来回答第n个球的查询。 / em>该数组中的索引。
由于我们的深度达到16,所以生成重复序列所需的操作总数为2 16-1 * 16 = 524288个操作。
为相同的https://ideone.com/uuNV2g共享代码
#include <iostream>
#include <map>
#include <vector>
using namespace std;
map<int, bool> states; // default value is False
int MAX_DEPTH = 16;
int dfs(int cur, int depth = 0) {
if(depth == MAX_DEPTH) {
return cur - (1<<MAX_DEPTH) + 1;
}
if(states[cur] == 0) {
states[cur] = !states[cur];
return dfs(2*cur, depth+1);
}
else {
states[cur] = !states[cur];
return dfs(2*cur+1, depth+1);
}
}
int main() {
int until = (1LL<<(MAX_DEPTH-1));
vector<int> pos; // 0 indexed
for(int i = 1; i <= until; i++) {
// cout << dfs(1) << ' ';
pos.push_back(dfs(1));
}
cout << pos[(12344%until)];
// 12344 instead of 12345 since the sequence is 0 indexed
}
希望它能解决。