一,思路:
1.做这种题你首先要想在什么情况下他是凑不出来一颗树的,只有想出这个之后再去想怎样高度最小,这样在思维上会有个过渡。
2.由于子节点数量为零他是叶子节点,是用来封底的。所以当叶子节点不足的时候,就无法构造了。我们接着分析,叶子节点的数量是和子节点数量为2的点数量 决定的 ,假如它的数量是x,那么叶子节点就要有 x+1个。
3.还有一个点,就是子节点数量为1的点是不会影响,能否构成数的,只会影响高度。
代码:
#include <iostream>
#include<algorithm>
#include<cmath>
#include<cstring>
#include<set>
#include<stack>
#include<queue>
#include<map>
using namespace std;
const int N=1e5+10;
typedef long long ll;
typedef pair<int,int> pii;
int arr[N];
void Solved() {
int a,b,c;
cin>>a>>b>>c;
if(a+1!=c){
cout<<-1<<endl;
return;
}
//当代码进行到这里,说明一定可以构成
//接下来我们尽可能让树变得对称,这样高度才会最低
int step=2;
arr[1]=1;
//先铺设节点为2的点
//预处理出来树的高度和所需节点为2的点的数量对应关系
for(int i=2;i<=30;i++){
arr[i]=arr[i-1]+step;
step<<=1;
}
//高度标记
int flag=0;
//最后一层还剩下几个点没处理----->有点抽象,举个例子:
2
2 2
2 2 2 2
2 2 ------->这边没铺满只能用节点为1/0的点来填补
int ex=0;
//看看只铺节点为2的点最多可以铺多高
for(int i=0;i<=30;i++){
if(arr[i]>=a){
flag=i;
ex=arr[i]-a;
break;
}
}
//联想节点为1的点不够,或者太多两种情况,画个图
if(ex>=b) cout<<flag<<endl;
else{
b-=ex;
flag+=(b+c-1)/c;
cout<<flag<<endl;
}
}
int main()
{
int t;
cin>>t;
while(t--) {
Solved();
}
return 0;
}