”双基“程序设计竞赛的一道题 寻根

寻根

Time Limit : 3000/1000ms (Java/Other)   Memory Limit : 65535/32768K (Java/Other)
Total Submission(s) : 118   Accepted Submission(s) : 29

Font: Times New Roman | Verdana | Georgia

Font Size: ← →

Problem Description

风雨漂泊异乡路,
浮萍凄清落叶飞。
游子寻根满愁绪,
一朝故土热泪归。
Hey ecjtuer! 刚刚学习了二叉树的知识,现在来考察一下..
给你一个深度为h的满二叉树,根节点为1(根的深度为0),根据先序遍历对节点进行编号,如下图是对一个深度为2的满二叉树的节点进行编号。
现在希望你告诉我以第n个叶子节点(从左往右数)为起点,终点为根节点,形成的一条链经过的节点的序号之和。


1
/
2 5
/ /
3 4 6 7

Input

输入两个数 h 代表二叉树的深度 n代表查询的叶子节点
1<=h<=50
1<=n<=2^h
注意多组数据

Output

输出所求链的序号之和模1e9+7的余数

Sample Input

2 3

Sample Output

12


  队友的奇妙解法,队里都觉得比题解还要好hhh,将n-1转化为二进制,然后从树根开始,遇到1往树的右边走,遇到0往左边走,加起来就是结果了,不过要理解二叉
树的性质和结构,能正确的推断出当前的数的值,其实也不难啦。
 1 #include<iostream>
 2 #include<cstring>
 3 #define LL long long
 4 #define stu 1000000007
 5 using namespace std;
 6 
 7 int main()
 8 {
 9     LL h,n;
10     while(cin>>h>>n)
11     {
12         LL num[50],i=0,sum=1,temp=1,ans=1;
13         memset(num,0,sizeof(num));
14         n=n-1;
15         while(n)
16         {
17             num[i++]=n%2;
18             n=n/2;
19         }
20         i=h;
21         while(h)
22         {
23             temp=1;
24             if(num[--i])
25             {
26                 for(int j = 1; j <= h; j++)
27                 {
28                     temp*=2;
29                 }
30                 ans+=temp;
31                 sum+=ans;
32                 sum=sum%stu;
33             }
34             else
35             {
36                 ans+=1;
37                 sum+=ans;
38                 sum=sum%stu;
39             }
40             h--;
41         }
42         cout<<sum<<endl;
43     }
44     return 0;
45 }
原文地址:https://www.cnblogs.com/Xycdada/p/6091678.html