A complete binary tree with a maximum depth of 16 is known, with all leaf nodes having the same depth. If a small ball is placed at the root node, the ball will begin to fall along the root node. There is a switch on each node in the complete binary tree. The default is all off. When the ball falls, the state of the switch changes whenever a ball falls on a switch. When the ball reaches a node, if the switch on the node is closed, go to the left to go to the ball, otherwise go to the right until it reaches the leaf node. Please help me find the leaf node number after the 12345th ball fell.
-
1This sounds like homework. This also has nothing to do with programming, it's a statistics/CPU question. – Jack Bashford Sep 02 '18 at 00:09
-
1What have you tried so far? – Mitch Sep 02 '18 at 00:42
-
Can I know how the leaf nodes are numbered? Starting from 1 maybe? Also by "find the leaf node number after the 12345th ball fell", you mean you need to know the number of the leaf node where this ball falls right? – Nilesh Sep 02 '18 at 01:51
-
1Here's a couple of things to think about, which might help you figure this one out. (You could also trying doing it on paper with a smaller tree, perhaps of depth 4.) **1.** Suppose you label every leaf with the sequence of switch settings which are needed to reach it. Does every leaf have a unique label? Why? **2.** Suppose the switches are set so that some leaf was just reached. What will be the label of the next leaf? – rici Sep 02 '18 at 03:16
1 Answers
You can simulate the given problem and notice that the leaf node at which the ball ends tends to repeat itself after a point of time. For example, for a binary tree of depth 3, the leaf nodes at which the ball ends for multiple roll of the balls are 1 3 2 4 1 3 2 4 1 3 2 4 . . .
(assuming the leaf nodes are numbered starting from 1). As visible, the sequence of length 23-1 = 4 keeps repeating itself. We can store this sequence in an array and answer the query for any nth ball throw by looking up the entry corresponding to the n mod 2depth-1 index in this array.
Since our depth is upto 16, the total number of operations required to generate the recurring sequence is 216-1 * 16 = 524288 operations.
Sharing the code for the same 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
}
Hope it works out.

- 1,388
- 6
- 17
-
There are some faster algorithms for reversing bits here: https://stackoverflow.com/a/746203 – rici Sep 02 '18 at 03:30
-
Thanks for the reference! But as visible, the total runtime for my given solution to produce the recurring sequence is about O(depth * 2^(depth-1)) which is sufficiently fine enough for the case when depth = 16 to run under 0.11 sec. – Nilesh Sep 02 '18 at 09:40
-
Sure. But if you just use bit reversal, you don't need the whole lookup tabke, since you can reverse 16 bits in a handful of instructions. – rici Sep 02 '18 at 11:47