大体题意
一棵树有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; } }