小球下落问题 求给位大神指教

mzoj 2014-07-16 01:10:26
有一颗二叉树,最大深度为D,所有叶子的深度都相同。所有结点从上到下从左到右的编号分别依次是1,2,3,4,~,(2的D次方-1)。在节点1放下一个小球,它会往下落。每个内结点都有一个状态(开或关),初始时,每个内结点都处于关闭状态,当小球经过一个内结点时,开关状态会改变。当为关闭状态时,小球向左落下;当为开状态时,小球向右走,直到走到叶子结点。
样例输入:
4 2
3 4
10 1
2 2
8 128
16 12345
样例输出:
12
7
512
3
255
36358

我的问题是前面的五组输入都可以得到正确的输出 但是最后一组输入却不行 16 12345 我得到的是65535 求大神指教问题出在哪???

#include <cstdio>
#include <cmath>
#include <cstdlib>
#include <cassert>
#include <queue>
using std ::queue;

// 结构声明
typedef struct node // 二叉树节点结构
{
int data; // 节点编号
int flag; // 节点开关
struct node * lchild ; // 左子树
struct node * rchild ; // 右子树
} BiNode ;

// 函数原型
BiNode * createTree( int n , int num ); // 创建满二叉树 n--小球总数 num--节点编号
void search( BiNode * root , int num , int last ); // 搜索小球所在叶子节点 root--根指针 num--节点编号 last--最后一个节点编号
//void levelOrder( BiNode * root );

int main( void )
{
int depth = 0 ; // 深度
int n = 0; // 小球个数
BiNode * root = NULL; // 根节点指针

while( scanf( "%d%d" , &depth , &n ) == 2 )
{
int t = pow( 2.0 , depth ) - 1 ; // 深度所能容纳的最大小球数

root = createTree( t ,1 ); // 初始化满二叉树

for( int i = 1 ; i <= n ; i ++ ) // 对n个小球进行下落
{
search( root , i , n );
}
//levelOrder( root );
//printf( "\n" );
}

return 0;
}

BiNode * createTree( int n , int num )
{
BiNode * root ;

assert( n > 0 );
assert( num > 0 );


root = ( BiNode * )malloc( sizeof( BiNode ) );
root -> data = num;
root -> flag = 0;

if( 2 * num <= n ) // 左子树存在 创建左子树
{
root ->lchild = createTree( n , 2 * num) ;
}
else
{
root ->lchild = NULL; // 倘若左子树不存在 那么也不会继续调用递归了 从而本函数执行完毕后 返回到上一层
}
if( 2 * num + 1 <= n ) // 右子树存在 创建左子树
{
root ->rchild = createTree( n , 2 * num + 1 );
}
else
{
root ->rchild = NULL;
}

return root ;
}
void search( BiNode * root , int num , int last )
{
assert( root );

if( root->lchild && root ->rchild ) // 内节点
{
if( root ->flag == 0 )
{
root ->flag = 1;
search( root ->lchild , num , last );
}
else
{
search( root ->rchild , num , last );
}
}
else // 叶子节点
{
if( num == last ) // 如果是最后一个节点 则输出编号
{
printf( "%d\n" , root ->data );
}
}

}
void levelOrder( BiNode * root )
{
queue < BiNode * > q;

assert( root != NULL );
q.push( root );

while( ! q.empty() )
{
root = q.front() ; q.pop();
printf( "%d " , root -> data );

if( root -> lchild )
{
q.push( root -> lchild );
}
if( root ->rchild )
{
q.push( root -> rchild );
}
}

}



...全文
258 2 打赏 收藏 转发到动态 举报
写回复
用AI写文章
2 条回复
切换为时间正序
请发表友善的回复…
发表回复
mzoj 2014-07-17
  • 打赏
  • 举报
回复
非常感谢 看了你的代码我才明白自己题意没完全理解 我之前以为只有碰到关闭开关时才需要打开 然后向左走 而碰到打开开关时可以直接向右走 还是非常感谢
caozl 2014-07-17
  • 打赏
  • 举报
回复


void search( BiNode * root , int num , int last )
{
	assert( root );

	if( root->lchild && root ->rchild )	 // 内节点
	{
		if( root ->flag == 0 )
		{
			root ->flag = 1;
			search( root ->lchild , num , last );
		}
		else	
		{
			root ->flag = 0;
			search( root ->rchild , num , last );
		}
	}
	else	 // 叶子节点
	{
		if( num == last )	 // 如果是最后一个节点 则输出编号
		{
			printf( "%d\n" , root ->data );
		}
	}
}
一点小错误 自己检查一下就好了

64,647

社区成员

发帖
与我相关
我的任务
社区描述
C++ 语言相关问题讨论,技术干货分享,前沿动态等
c++ 技术论坛(原bbs)
社区管理员
  • C++ 语言社区
  • encoderlee
  • paschen
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
  1. 请不要发布与C++技术无关的贴子
  2. 请不要发布与技术无关的招聘、广告的帖子
  3. 请尽可能的描述清楚你的问题,如果涉及到代码请尽可能的格式化一下

试试用AI创作助手写篇文章吧