• Codeforces Round #386 (Div. 2) 746G(树的构造)


    大体题意

    一棵树有n个结点,告诉你每层深度上有a[i]个结点,以及有多少叶子结点

    让你生成这棵树

    题解:考虑一颗树,如果满足每层深度上有a[i]结点,最多能有多少叶子结点

       那么答案很简单,就是对(a[i]-1)求和再加1(每一层的结点都集中在上一层的一个结点上)

         同理,我们考虑最少能有多少叶子结点,就是把上一个的答案再减去min(a[i]-1, a[i-1]-1)的求和,就是每一层的结点都尽可能的分散在上一层的结点上

       根据这个,那么如果要求有k个叶子节点,k在最大值与最小值之间,就可以生成出这棵树了

       生成的方法,和构造起来差不多,就是先求出最大值与k的差T,然后每一层处理时,如果T>0,就使这一层尽可能的分散在上一层结点上,然后T减少一点

       直到T为0,之后的层都直接集中在上一层的一个结点即可

    #include <iostream>
    #include <cstdio>
    using namespace std;
    const int maxn = 2*111111;
    int n, t, k;
    int a[maxn];
    int main()
    {
        cin>>n>>t>>k;
        for(int i = 1; i <= t; i++) cin>>a[i];
        int ans = 0;
        for(int i = 1; i < t; i++) ans += (a[i]-1); ans += a[t];
        int ans2 = ans;
        for(int i = 2; i <= t; i++) ans2 -= min(a[i-1]-1, a[i]-1);
        if(k <= ans && k >= ans2)
        {
            int T = ans - k;
            cout<<n<<endl;
            for(int i = 2; i <= 1+a[1]; i++)
                cout<<"1 "<<i<<endl;
            int tot = 2+a[1];
            for(int i = 2; i <= t; i++)
            {
                int tt = min(a[i-1]-1, a[i]-1), ttt = 0;
                while(T > 0 && tt > 0)
                {
                    if(ttt > 0) { T--; tt--; }
                    cout<<tot-a[i-1]+ttt<<" "<<tot+ttt<<endl;
                    ttt++;
                }
                if(T == 0 || tt == 0)
                {
                    while(ttt < a[i])
                    {
                        cout<<tot-a[i-1]<<" "<<tot+ttt<<endl;
                        ttt++;
                    }
                }
                tot += a[i];
            }
        } else
        {
            cout<<"-1"<<endl;
        }
    }
  • 相关阅读:
    Springboot websocket学习Demo
    webpack与vue使用
    图片服务器图片剪切处理
    时间字段设置默认值
    函数的递归
    数据类型检测及封装
    隔行变色
    if-else案例–开关灯
    作用域
    数据类型核心操作步骤和原理
  • 原文地址:https://www.cnblogs.com/Saurus/p/6197311.html
Copyright © 2020-2023  润新知