A - Dropping Balls UVA - 679(规律二叉树)

在这里插入图片描述
在这里插入图片描述
题意:就是给一个深度为D的完全二叉树;然后给I个小球,初始时所有节点为0;如果来了一个小球,那么这个节点先变成1,然后这个球往左孩子走,如果再来一个球,那么这个节点就先变为0,然后往右孩子走;问最后一个小球落到的节点编号;
其实这道题我拿着感觉有点懵逼;最简单的想法就是每个节点每个球去枚举一下但是想想时间复杂度ITD,早就超时了;
但是我可以发现这个规律:
在这里插入图片描述
对1号节点,如果I为奇数,说明最后一个球会使得1号节点从0–》1,那么就是往左边走;(因为节点初始都为0);如果I是偶数,那么最后一个球就会使得1号节点从1–》0那么就会往右边走,所以我可以算出来2号节点有多少个球走,3号节点有多少个球走(因为这里是动态的,所以你想成这样就更好理解些:就是2号节点存了多少个球,3号节点存了多少个球);然后按照这个思路又从2,3开始这样分析,就可以知道每个节点所存的球的个数;最后根据层数来判定截止;所以AC代码:

#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
int T,D,I;
int k;
void solve(){
    while(T--){
    scanf("%d %d",&D,&I);
         k=1;//因为小球都是从第1个节点开始的
         int d=1;//深度
         while(d<D){//其实这里感觉就像第I个小球混着其他小球一个下降
              if(I&1)k=2*k,I=(I+1)/2;//如果为有奇数的小球,那么他会往左走;并且左边会存有(I+1)/2个小球
              else k=2*k+1,I=I/2;//如果有偶数个小球,那么他会往右走;并且右边会有I/2个小球;
                d++;//然后下一层
         }
      printf("%d\n",k);
    }
}
int main(){
    scanf("%d",&T);//组数
    if(T!=-1)solve();
    return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值