第三题(20分)
题目描述:
有一颗二叉树,最大深度为D,且所有叶子的深度都相同。所有结点从左到右从上到下的编号为1,2,3,·····,2的D次方减1。在结点1处放一个小猴子,它会往下跑。每个内结点上都有一个开关,初始全部关闭,当每次有小猴子跑到一个开关上时,它的状态都会改变,当到达一个内结点时,如果开关关闭,小猴子往左走,否则往右走,直到走到叶子结点。
一些小猴子从结点1处开始往下跑,最后一个小猴儿会跑到哪里呢?
输入格式
输入二叉树叶子的深度D,和小猴子数目I,假设I不超过整棵树的叶子个数,D<=20.
输出格式
输出第I个小猴子所在的叶子编号。
样例输入
4 2
样例输出
12
解题思路:
可以将有关二叉树和猴子的信息封装进类,由于是完全二叉树,用顺序存储方式保存结点。用布尔数组模拟开关,向左为 2 * i,向右为 2 * i + 1。通过后序递归遍历二叉树,最后一只猴子的list中的第一个值即为到达的叶子结点。
java代码:
import java.io.*;
import java.util.*;
public class Main {
public static void main(String[] args) throws IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
String[] split = br.readLine().split(" ");
int d = Integer.parseInt(split[0]);
int n = Integer.parseInt(split[1]);
Temp1094 temp = new Temp1094(d, n);
temp.travel();
}
}
class Temp1094{
int d;
int n;
boolean []f;
int num;
List<Integer> list = new ArrayList<>();
public Temp1094(int d, int n) {
this.d = d;
this.n = n;
num = (int)Math.pow(2, d);
f = new boolean[num];
}
public void tra(int i,int j) {
if(i > num -1) {
return;
}
if(f[i]) {
tra(2 * i + 1 , j);
if(j == n) {
list.add(i);
}
f[i] = false;
}else {
tra(2 * i , j);
if(j == n) {
list.add(i);
}
f[i] = true;
}
}
public void travel() {
for(int i = 1; i <= n;i++) {
tra(1 , i);
}
System.out.println(list.get(0));
}
}