題意理解:就是讓你在滿二叉樹上尋找規律,根據給出的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;
}