A Rational Sequence(思維)

歡迎訪問https://blog.csdn.net/lxt_Lucia~~

宇宙第一小仙女\(^o^)/~~萌量爆表求帶飛=≡Σ((( つ^o^)つ~ dalao們點個關注唄~~

 

----------------------------------------我只是一條可愛噠分界線-------------------------------------------

一、問題:

Description

An infinite full binary tree labeled by positive rational numbers is defined by:
• The label of the root is 1/1.
• The left child of label p/q is p/(p+q).
• The right child oflabel p/q is (p+q)/q.

The top of the tree is shown in the following figure:

å¨è¿éæå¥å¾çæè¿°

A rational sequence is defined by doing a level order (breadth first) traversal of the tree (indicated
by the light dashed line). So that:
F(1) = 1/1, F(2) = 1/2, F(3) = 2/1, F(4) = 1/3, F(5) = 3/2, F(6) = 2/3, . . .

Write a program which takes as input a rational number, p/q, in lowest terms and finds the next
rational number in the sequence.
That is, if F(n) = p/q, then the result is F(n + 1).

 

Input

The first line of input contains a single integer P, (1 ≤ P ≤ 1000), which is the number of data sets
that follow. Each data set should be processed identically and independently.
Each data set consists of a single line of input. It contains the data set number, K, which is then
followed by a space, then the numerator of the fraction, p, followed immediately by a fonward slash (/),
followed immediately by the denominator of the fraction, q. Both p and q will be relatively prime and
0 ≤ p, q ≤ 2147483647.

 

Output

For each data set there is a single line of output. It contains the data set number, K, followed by a
single space which is then followed by the numerator of the fraction, followed immediately by a forward
slash (‘/’) followed immediately by the denominator of the fraction. Inputs will be chosen such that
neither the numerator nor the denominator will overflow a 32-bit integer.

 

Sample Input

5
1 1/1
2 1/3
3 5/2
4 2178309/1346269
5 1/10000000

 

Sample Output

1 1/2
2 3/2
3 2/5
4 1346269/1860498
5 10000000/9999999

 

二、題意:

如圖所示,根爲1/1,假設某結點是p/q,則其左子樹爲p/(p+q),右子樹爲(p+q)/q,按此規律畫一棵樹,已知第n個結點是p/q,求第n+1個結點。

 

三、思路:

其實之前做過一個非常類似的題目,戳這裏~,那個題是給出n求第n個結點,受那題影響,於是做這個題爲最初的思路是:除了特判,其他的由當前結點開始,向上搜,每次記錄,用0和1分別表示當前結點是上一結點的左子樹還是右子樹,然後再從根結點回來找到下一個,很不幸,RE了5發,按此思路也能做,但是很麻煩,易出錯,沒必要。

在最後還剩半個小時的時候,想出了第二種思路,簡單的不能再簡單了,但是來不及敲了。下面介紹一下第二種思路,畫出前五層,仔細觀察,就發現規律了,無非就以下5種情況:

1)根結點,1/1,注意它的下一結點是1/2不是2/1。

2)p=1,即樹最左邊的那一列;q=1,即樹最右邊那一列。

3)q=2,即樹最中心的兩列,位置對稱,值也對稱。

4)p<q,即左子樹,推其父親節點爲a/(b-a),由此再算右子樹即可。

5)p>q,即右子樹,此種情況最爲麻煩,由當前結點不斷找父親節點,直到找到第一個p<q(是左子樹)的父親節點A,記錄下尋找次數ans,然後順着該結點的兄弟B的左子樹找ans次,順推出結果。注意此時無需考慮下一個結點會是樹的下一層,此情況已包含在第2種情況中。

 

四、代碼:

#include<cstdio>
int main()
{
    int T,k;
    long long p,q;
    scanf("%d",&T);
    while(T--)
    {
        scanf("%d %lld/%lld",&k,&q,&p);
        if(p==1 && q==1)
            printf("%d 1/2\n",k);
        else if(p==1)
            printf("%d 1/%lld\n",k,q+1);
        else if(q==1)
            printf("%d %lld/%lld\n",k,p,p-q);
        else if(p==2)
            printf("%d %lld/%lld\n",k,p,q);
        else if(q<p)
            printf("%d %lld/%lld\n",k,p,p-q);
        else
        {
            int ans=0;
            while(p<=q)
            {
                q-=p;
                ans++;
            }
            printf("%d %lld/%lld\n",k,p,p-q+ans*p);
        }
    }
    return 0;
}

 

------------------------------------------我也是有底線的----------------------------------------------------

歡迎訪問https://blog.csdn.net/lxt_Lucia~~

宇宙第一小仙女\(^o^)/~~萌量爆表求帶飛=≡Σ((( つ^o^)つ~ dalao們點個關注唄~~

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章