/*
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;
}