- 题目描述:
-
如上所示,由正整数1,2,3……组成了一颗特殊二叉树。我们已知这个二叉树的最后一个结点是n。现在的问题是,结点m所在的子树中一共包括多少个结点。
比如,n = 12,m = 3那么上图中的结点13,14,15以及后面的结点都是不存在的,结点m所在子树中包括的结点有3,6,7,12,因此结点m的所在子树中共有4个结点。
- 输入:
-
输入数据包括多行,每行给出一组测试数据,包括两个整数m,n (1 <= m <= n <= 1000000000)。最后一组测试数据中包括两个0,表示输入的结束,这组数据不用处理。
- 输出:
-
对于每一组测试数据,输出一行,该行包含一个整数,给出结点m所在子树中包括的结点的数目。
- 样例输入:
-
3 12 0 0
- 样例输出:
-
4
这是解决完全二叉树的题目,其中完全二叉树有性质:若2*i<=n,则i的左子女为2*i;若2*i+1<=n,则i的右子女为2*i+1.
我最开始的想法是用递归的方法构建一颗完全二叉树,结果Memory Limit Exceed,代码如下:
View Code1 #include <iostream> 2 #include <malloc.h> 3 using namespace std; 4 5 typedef struct BiTNode 6 { 7 int data; 8 struct BiTNode *lc, *rc; 9 }BiTNode, *BiTree; 10 11 int creatT(BiTree &T, int m, int n, int i, int &cnt) 12 { 13 T = (BiTree)malloc(sizeof(BiTNode)); 14 T->data = i; 15 16 if(i == m) 17 cnt++; 18 19 if(2*i <= n) 20 { 21 if(cnt >= 1)cnt++; 22 creatT(T->lc, m, n, 2*i, cnt); 23 } 24 else T->lc = NULL; 25 if(2*i+1 <= n) 26 { 27 if(cnt >= 1)cnt++; 28 creatT(T->rc, m, n, 2*i+1, cnt); 29 } 30 else T->rc = NULL; 31 return cnt; 32 } 33 34 int main() 35 { 36 int m, n, cnt; 37 BiTree T; 38 while(cin>>m>>n &&m&&n) 39 { 40 T = NULL; 41 cnt = 0; 42 creatT(T, m, n, 1, cnt); 43 cout<<cnt<<endl; 44 } 45 return 0; 46 }
后来改成了非递归的方法,l为每层最左边的数,即最小值;r为每层最右边的数,即最大值,结果AC,代码如下:
View Code1 #include <iostream> 2 using namespace std; 3 4 int main() 5 { 6 int m, n; 7 int count, l, r; 8 while(cin>>m>>n &&n&&m) 9 { 10 if(m == n)count = 1; 11 else if(m < n) 12 { 13 count = 1; 14 l = 2*m; 15 r = 2*m+1; 16 while(r <= n) 17 { 18 count += r-l+1; 19 l = 2*l; 20 r = 2*r+1; 21 } 22 if(n >= l) 23 count += n-l+1; 24 } 25 cout<<count<<endl; 26 } 27 return 0; 28 }

浙公网安备 33010602011771号