Codeforces 1237 E Balanced Binary Search Trees —— 构造类似完全二叉树

This way

题意:

现在有1-n这么多点,你要用这些点构成一个二叉树,使得这个二叉树满足以下条件:
1.任意一个节点与其右儿子的奇偶性相同
2.任意一个节点与其左儿子的奇偶性相反
3.所有节点的深度加起来最小

题解:

这道题真的是让我大吃一斤。有很多的解法啊,但是很明显我是去看最简单的那种,然后我就懵逼了半天,不知所措。
首先深度之和最小的意思就是类似一个完全二叉树,叶子结点的深度差不超过1.
然后它的模数是骗人的,总共只有两种可能,要么是0,要么是1,因为他有一定的构成方法,不会出现第二种可能(为什么,我也不是很懂)
首先n=1的时候就是1个点。
n=2的时候就是1是2的左二子
n=3的时候不可能。
n=4的时候是样例
然后有一些很重要的性质去发现:
首先n一定是在最右下角。因为它是最大的,然后n与根节点的奇偶性相同,那么根节点右子树的大小一定是偶数的。
那么对于n=5的时候,很明显不能在右子树上加东西,因为那样会破坏平衡,如果根节点变动的话,右子树就至少变成4,那么这棵树又不平衡了。所以只能往最左下角加一个点,使这棵树平衡(也就是将所有点的值+1,再往左下角加一个点)。但是这种方法对于6的时候不行了,因为没有位置可以给你去放,增加一个点的同时势必还要增加一个点,这样就不满足了:
在这里插入图片描述
比如你增加一个红色的,那么就一定要增加一个黄色的,因为同奇偶的约束。
这样的话就不满足深度之和最小这个条件。如果要满足这个条件,那么就必须在右边也加上两个点。
那么我们就可以发现一个规律:
两个相同深度的平衡的树可以连起来,比如4,就是1和2相连。9就是4和4相连。
但是如果这棵树是奇数的,就必须在左下角添加一个节点才能连上去,因为右子树必须是偶数的。
那么就得出了现在的程序:

#include<bits/stdc++.h>
using namespace std;
int main()
{
    int n;
    scanf("%d",&n);
    int now=1;
    while(now+1<n){
        if(now&1)
            now=(now)+(1)+(now+1);
        else
            now=(now)+(1)+(now);
    }
    if(now==n||now+1==n)
        printf("1\n");
    else
        printf("0\n");
    return 0;
}

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值