有理數樹 遞迴

2021-10-04 16:22:09 字數 1857 閱讀 5634

十九世紀的時候,moriz stern (1858)與achille brocot (1860)發明了「一棵樹」。據說,經由一些簡單的規則而產生的這一棵樹上,可以包含零以上所有的有理數。這棵樹看起來大致這樣:

你觀察出規則了嗎?

首先,他們在第一列放兩個「分數」,第乙個是0 / 1,代表0;第二個是1 / 0,代表無窮大。接著他們一列一列地產生這棵樹,當他們要產生第k+1列的時候,就先把前k列所有的分數按照大小排成一列(假設有n個),在這些數之間會有n - 1個間隔,那麼第k + 1列就準備產生n - 1個數,其值的分子恰好是左右兩個數的分子的和、分母是左右兩個數的分母的和。

例如,2 / 3,而它的2就是左邊1 / 2的1和右邊1 / 1的分子1相加的結果;而2 / 3的3,則是1 / 2的2加上1 / 1的分母1而得。

從這棵樹中,我們可以看出,每個正的最簡分數在這棵樹中恰好出現一次,我們用字母「l」和「r」分別表示從樹根(1 / 1)開始的一步「往左走」和「往右走」,則每乙個數都可以由l和r組成的序列表示。

例如,lrrl表示從1 / 1開始往左走一步到1 / 2,然後往右走到2 / 3,再往右走到3 / 4,最後往左走到5 / 7。我們可以把lrrl看作5 / 7的一種表示法。幾乎每個正分數均有唯一的方法表示成乙個由l和r組成的序列。

給定乙個分數,輸出它的lr表示法。

輸入輸入有兩個互素的正整數m和n(1 ≤ n,m ≤1000)。

輸出輸出對應的lr表示法。

樣例輸入 copy

5 7樣例輸出 copy

lrrl

不難發現每個數都可以由上面的樹的資料得到,且當前結點的左邊一定小於大當前結點,右邊大於當前結點。

就比如 1 / 4 是由 0 / 1 和 1 / 3 得到的 ,可以考慮記錄每個節點的值和其左右的結點,讓後遞迴處理即可。

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#define x first

#define y second

using

namespace std;

typedef

long

long ll;

typedef pair<

int,

int> pii;

const

int n=

1000010

,mod=

1e9+

7,inf=

0x3f3f3f3f

;const

double eps=

1e-6

;int n,m;

double x;

struct node

tr[n]

;void

dfs(

int u)

;printf

("l");

dfs(u+1)

;}else

if(tr[u]

.y;printf

("r");

dfs(u+1)

;}}int

main()

;dfs(1

);return0;

}

有理數均值

本題要求編寫程式,計算n個有理數的平均值。輸入第一行給出正整數n 100 第二行中按照a1 b1 a2 b2 的格式給出n個分數形式的有理數,其中分子和分母全是整形範圍內的整數 如果是負數,則負號一定出現在最前面。在一行中按照a b的格式輸出n個有理數的平均值。注意必須是該有理數的最簡分數形式,若分...

有理數比較大小及有理數相加

本題要求編寫程式,比較兩個有理數的大小,並且計算兩個有理數的和。輸入格式 在一行中按照a1 b1 a2 b2的格式給出兩個分數形式的有理數,其中分子和分母全是整形範圍內的正整數。輸出格式 在一行中按照a1 b1 a2 b2的格式輸出兩個有理數比較大小 在一行中按照a b的格式輸出兩個有理數的和。注意...

5 33 有理數加法

本題要求編寫程式,計算兩個有理數的和。輸入格式 輸入在一行中按照a1 b1 a2 b2的格式給出兩個分數形式的有理數,其中分子和分母全是整形範圍內的正整數。輸出格式 在一行中按照a b的格式輸出兩個有理數的和。注意必須是該有理數的最簡分數形式,若分母為1,則只輸出分子。輸入樣例1 1 3 1 6 輸...