完全2叉树 应用

/*
Name: 
Copyright: 
Author: 
Date: 18/07/11 16:43
Description:
          一颗完全2叉树深度设为D,root深度假设为1,树中每个节点是个开关,默认开关关闭,当小球到达节点时候,如果开关关闭则
         落入下层左孩子处,如果开关打开则落向下一次右孩子处。然后该节点开关属性发生变化。
         现在输入数的高度 height 和小球的数量 ballnum 计算最后一个求落下来的时候,落在那个位置。
        示例输入,输出:
        4 2
        3 4
        16 12345
        输出:
          12
          7
          36358 
非模拟的方法,见下一篇文章描述
*/
/*
 完全2叉树可以利用数组存数,存储有点不同,从小标1开始。index的左孩子 index*2  右孩子index*2 + 1
 index 父亲节点【index/2】 对下取整。 
*/
#include<iostream>
#include<vector>
#include<cmath>
using std::vector;
using std::cin;
using std::cout; 
using std::endl;
struct SNode
{
    int iValue;
    bool bIsOpened;
}; 
//尽量避免传参数时候,传递vector非引用,函数传参,传值会复制实参。开销比较大,vector如果只是访问不改变
//一般建议传入const_iterator 遍历便可,便利可以随机遍历。iterator + n .
//需要插入删除,传入引用。如果修改传入迭代器。 
void InputInitTree(vector<SNode>  &stdVecTree,const int &iTreeHeight) 
{
    SNode sTempNode;
    long lTreeNodeNum = static_cast<long>(pow(2.0,iTreeHeight) - 1);//这里注意精度。 
    for(long lIndex = 0; lIndex != lTreeNodeNum; lIndex++)
    {
        sTempNode.iValue = lIndex;
        sTempNode.bIsOpened = false;
        stdVecTree.push_back(sTempNode);
    }    
} 

int SimulateFallProcess(vector<SNode>::iterator &iterBegin,vector<SNode>::iterator &iterEnd,const int &iBallNum, const int &iHeight) {

    int iCurIndex = 1;     for(int iTimes = 1; iTimes != iBallNum + 1 ;iTimes++)// ball number     {         iCurIndex = 1;//避免每个小球相互干扰,每次初始化很重要         for(int iLayer = 1 ; iLayer != iHeight; iLayer++)//layer iLayer != iHeight beacuse the 2th last layer we can calculate the last layer         {             if((*(iterBegin + iCurIndex -1)).bIsOpened)//right clild open 注意运算优先级别 .优先级别高于*             {                 (*(iterBegin + iCurIndex -1)).bIsOpened =  !(*(iterBegin + iCurIndex -1)).bIsOpened; //注意题目是状态改变。所以取反                 iCurIndex = iCurIndex * 2 + 1;             }                else//left clild close             {                 (*(iterBegin + iCurIndex -1)).bIsOpened =  !(*(iterBegin + iCurIndex -1)).bIsOpened;                 iCurIndex = iCurIndex * 2;             }

        }         }     return iCurIndex ;   }

int main() { vector<SNode> stdVecTree; int iHeight = 0; int iBallNum = 0; int iLastFalledNum = 0; while(cin>>iHeight && cin>>iBallNum) { stdVecTree.clear(); InputInitTree(stdVecTree,iHeight); iLastFalledNum = SimulateFallProcess(stdVecTree.begin(),stdVecTree.end(),iBallNum,iHeight); cout<<iLastFalledNum<<endl; } return 0; }

 
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值