题意理解:就是让你在满二叉树上寻找规律,根据给出的p,q推出对应的编号;
思路:显然,p<q时是左儿子,p>q是右儿子,p=q是根节点;然后继续观察规律;我们可以轻易求出位于树上最左边和最右边上的点的编号;分别为2^(q-1),2^q-1;
并且;如果不断沿着左儿子的方向走,q以p递增;右儿子则p以q递增;所以只要我们知道一个起点就可以推出它所有后继点的编号。我们可以利用树的特性,写一个很方便的递归函数,减少代码量。
代码:
#include<bits/stdc++.h>
long long work(long long p,long long q)//求出值为p/q的点的编号
{
long long a,k,ans;
if(p==1&&q==1)
return 1;
if(p==0||q==0)
return 1;
if(p>q)//右儿子
{
k=p/q;
if(p%q==0)//到达根节点时,特判,下同
k--;
a=work(p%q,q);
ans=pow(2,k)*a+pow(2,k)-1;//找规律
return ans;
}
else if(p<q)//左儿子
{
k=q/p;
if(q%p==0)
k--;
a=work(p,q%p);
ans=pow(2,k)*a;//找规律
return ans;
}
}
int main()
{
long long t,p,q,a;
scanf("%lld",&t);
while(t--)
{
scanf("%lld %lld/%lld",&a,&p,&q);
printf("%lld %lld\n",a,work(p,q));
}
return 0;
}