我的PAT系列文章更新重心已移至Github,歡迎來看PAT題解的小伙伴請到Github Pages瀏覽最新內容。此處文章目前已更新至與Github Pages同步。歡迎star我的repo。
題目
一個分數一般寫成兩個整數相除的形式: ,其中
不為0。最簡分數是指分子和分母沒有公約數的分數表示形式。
現給定兩個不相等的正分數 和
,要求你按從小到大的順序列出它們之間分母為
的最簡分數。
輸入格式:
輸入在一行中按 的格式給出兩個正分數,隨后是一個正整數分母
,其間以空格分隔。題目保證給出的所有整數都不超過 1000。
輸出格式:
在一行中按 的格式列出兩個給定分數之間分母為
的所有最簡分數,按從小到大的順序,其間以 1
個空格分隔。行首尾不得有多余空格。題目保證至少有 1 個輸出。
輸入樣例:
7/18 13/20 12
輸出樣例:
5/12 7/12
思路
一個坑就是給出的兩個分數并沒有指定誰大誰小,看了別人的解法才反應過來的。怪不得通過率只有0.18。
還有一個注意點就是開始結束的點:
- 不能等于給出的兩個分數,因為要求“兩個數之間的”最簡分數
- 開始點:需要 L > K * N1 / M1 >= L - 1,由于C語言整型的“地板除”運算,一定有 K * N1 / M1 = L - 1,那么初始點就是 L = K * N1 / M1 + 1。這樣不需要用循環來確定。
- 結束點:要避免“地板除”帶來的問題,使用 N2 * K > M2 * L 作為判斷標準。
代碼
最新代碼@github,歡迎交流
#include <stdio.h>
int gcd(int a, int b)
{
for(int r; (r = a % b); a = b, b = r) ;
return b;
}
int main()
{
int N1, N2, M1, M2, K, L, count = 0;
scanf("%d/%d %d/%d %d", &N1, &M1, &N2, &M2, &K);
if(N1 * M2 > N2 * M1)
{
L = N1, N1 = N2, N2 = L;
L = M1, M1 = M2, M2 = L;
}
for(L = N1 * K / M1 + 1; N2 * K > M2 * L; L++)
if(gcd(L, K) == 1)
printf("%s%d/%d", count++ ? " " : "", L, K);
return 0;
}