题目1113:二叉树(二叉树结点问题)

题目1113:二叉树

两种方法解决,都利用了二叉树的性质

时间限制:1 秒

内存限制:32 兆

题目描述:

如上所示,由正整数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思路:

令父节点的标号为i, 若左孩子存在,那么左孩子的标号为2*i,若右孩子存在,那么右孩子标号为2*i+1。根据这个性质我便一层一层搜,若不到最后一层,那么当前层的结点便可以全部加上,而不必挨个去计数。其实最后一层也不必挨个去计数,只要最后一层的尾结点的标号大于最左孩子的标号,那么便可以用尾结点下标剪去最左孩子的下标加1.
#include <iostream>
#include<string.h>
#include<stdio.h>
using namespace std;

int main()
{
    int m,n,sum,left,right;
    while(scanf("%d%d",&m,&n)!=EOF&&(m||n))
    {
      sum=0;
      if(m==n) sum=1;
      else
      {
          if(m<=n) sum=1;
          left=2*m;
          right=2*m+1;
          while(n>right)
          {
              sum+=(right-left+1);
              left*=2;
              right=right*2+1;
          }
          if(n>=left) sum=sum+(n-left)+1;
      }
       printf("%d\n",sum);
    }
    return 0;
}

方法2

#include <iostream>
#include<string.h>
#include<stdio.h>
#include<math.h>
using namespace std;

int main()
{
    long long m,n,sum,left,right;
    while(scanf("%lld%lld",&m,&n)!=EOF&&(m||n))
    {
      sum=0;
      int i=0;
      left=m;
      right=m;
      while(right<=n)
      {
          sum+=int(pow(2.0,i++));
          right=right*2+1;//右子树
          left*=2;//左子树
      }
      //下一层右子树不存在时
      while(left<=n)
      {
          sum++;
          left++;
      }
      printf("%lld\n",sum);
    }
    return 0;
}

/**************************************************************
    Problem: 1113
    User: zhuoyuezai
    Language: C++
    Result: Accepted
    Time:0 ms
    Memory:1608 kb
****************************************************************/

时间: 2025-01-08 10:43:41

题目1113:二叉树(二叉树结点问题)的相关文章

题目1113:二叉树

题目描述: 如上所示,由正整数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,表示输

数据结构课程设计题目四_二叉树

本文出自:http://blog.csdn.net/svitter 题目4:二叉树 给出一颗无线的二叉树.树的每一个结点用一整数对标识.二叉树构造如下 树根被标识为(1, 1): 如果一个结点被标识为(a, b), 则其左孩子被标识为(a+b,b),右孩子被标识为(a, a+b).现在给出某一结点(a, b),求树根到该结点的最短路径,并且同时求出从树根出发向左走和向右走的次数.建议完成人数1人. 注:此处使用了STL_stack库函数,是不允许的,我图方便. //===============

九度oj 题目1078:二叉树遍历

题目1078:二叉树遍历 时间限制:1 秒 内存限制:32 兆 特殊判题:否 提交:5326 解决:3174 题目描述: 二叉树的前序.中序.后序遍历的定义: 前序遍历:对任一子树,先访问跟,然后遍历其左子树,最后遍历其右子树: 中序遍历:对任一子树,先遍历其左子树,然后访问根,最后遍历其右子树: 后序遍历:对任一子树,先遍历其左子树,然后遍历其右子树,最后访问根. 给定一棵二叉树的前序遍历和中序遍历,求其后序遍历(提示:给定前序遍历与中序遍历能够唯一确定后序遍历). 输入: 两个字符串,其长度

题目1368:二叉树中和为某一值的路径

题目描述: 输入一颗二叉树和一个整数,打印出二叉树中结点值的和为输入整数的所有路径.路径定义为从树的根结点开始往下一直到叶结点所经过的结点形成一条路径. 输入: 每个测试案例包括n+1行: 第一行为2个整数n,k(1<=n<=10000),n表示结点的个数,k表示要求的路径和,结点编号从1到n. 接下来有n行.这n行中每行为3个整数vi,leftnode,rightnode,vi表示第i个结点的值,leftnode表示第i个结点的左孩子结点编号,rightnode表示第i个结点的右孩子结点编号

题目1078:二叉树遍历

时间限制:1 秒 内存限制:32 兆 题目描述: 二叉树的前序.中序.后序遍历的定义:前序遍历:对任一子树,先访问跟,然后遍历其左子树,最后遍历其右子树:中序遍历:对任一子树,先遍历其左子树,然后访问根,最后遍历其右子树:后序遍历:对任一子树,先遍历其左子树,然后遍历其右子树,最后访问根.给定一棵二叉树的前序遍历和中序遍历,求其后序遍历(提示:给定前序遍历与中序遍历能够唯一确定后序遍历). 输入: 两个字符串,其长度n均小于等于26.第一行为前序遍历,第二行为中序遍历.二叉树中的结点名称以大写字

九度oj 题目1368:二叉树中和为某一值的路径

题目描述: 输入一颗二叉树和一个整数,打印出二叉树中结点值的和为输入整数的所有路径.路径定义为从树的根结点开始往下一直到叶结点所经过的结点形成一条路径. 输入: 每个测试案例包括n+1行: 第一行为2个整数n,k(1<=n<=10000),n表示结点的个数,k表示要求的路径和,结点编号从1到n. 接下来有n行.这n行中每行为3个整数vi,leftnode,rightnode,vi表示第i个结点的值,leftnode表示第i个结点的左孩子结点编号,rightnode表示第i个结点的右孩子结点编号

算法题——二叉树中结点的最远距离

题目:给定一棵二叉树,结点的距离就是两个结点之间路径包含的结点的数目,求结点的最大距离. 可以参考这两篇文章:<编程之美: 求二叉树中节点的最大距离>的另一个解法 和 Tree Diameter 思路: 在每一个结点处,求两个信息:以该结点为根的树的高度,以及以该结点为根的树中包含的最大距离. 因为所求的最大距离,如果是跨越根结点的,则为两个子树的树高度之和+1,如果是不跨越根结点的,则为左右子树中的最大距离的最大值. 代码: ①参考第一篇文章,每次返回两个值: 1 struct TreeNo

Swust OJ973: 统计利用先序遍历创建的二叉树叶结点的个数

题目简述 利用先序递归遍历算法创建二叉树并计算该二叉树叶结点的个数. 输入 接受键盘输入的由大写英文字符和"#"字符构成的一个字符串(用于创建对应的二叉树). 输出 输出对应的二叉树叶结点的个数. 样例输入复制 ABCD###EF##G### A##B## #A 样例输出复制 3Step One:先序递归遍历算法创建二叉树 void CreateTree(BiTree *&tree) { char ch; cin>>ch; if(ch=='#') tree=NULL

九度 1113 关于二叉树节点的个数问题

#include <stdio.h> #include <math.h> int main() { int n,m,left,right; int count; int deep_n,deep_m,deep_diff; int i, j; for( scanf("%d%d",&m,&n); n!=0 && m!=0; scanf("%d%d",&m,&n) ) { count = 0; left