hdu 1717 小數化分數2 (數學)
小數化分數2
Time Limit: 1000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 2022 Accepted Submission(s): 813
請你寫一個程式不但可以將普通小數化成最簡分數,也可以把迴圈小數化成最簡分數。
Input 第一行是一個整數N,表示有多少組資料。
每組資料只有一個純小數,也就是整數部分為0。小數的位數不超過9位,迴圈部分用()括起來。
Output 對每一個對應的小數化成最簡分數後輸出,佔一行。 Sample Input 3 0.(4) 0.5 0.32(692307) Sample Output 4/9 1/2 17/52 Source
眾所周知,有限小數是十進分數的另一種表現形式,因此,任何一個有限小數都可以直接寫成十分之幾、百分之幾、千分之幾……的數。那麼無限小數能否化成分數?
首先我們要明確,無限小數可按照小數部分是否迴圈分成兩類:無限迴圈小數和無限不迴圈小數。無限不迴圈小數不能化分數,這在中學將會得到詳盡的解釋;無限迴圈小數是可以化成分數的。那麼,無限迴圈小數又是如何化分數的呢?由於它的小數部分位數是無限的,顯然不可能寫成十分之幾、百分之幾、千分之幾……的數。其實,迴圈小數化分數難就難在無限的小數位數。所以我就從這裡入手,想辦法“剪掉”無限迴圈小數的“大尾巴”。策略就是用擴倍的方法,把無限迴圈小數擴大十倍、一百倍或一千倍……使擴大後的無限迴圈小數與原無限迴圈小數的“大尾巴”完全相同,然後這兩個數相減,“大尾巴”不就剪掉了嗎!我們來看兩個例子:
⑴ 把0.4747……和0.33……化成分數。
想1: 0.4747……×100=47.4747……
0.4747……×100-0.4747……=47.4747……-0.4747……
(100-1)×0.4747……=47
即99×0.4747…… =47
那麼 0.4747……=47/99
想2: 0.33……×10=3.33……
0.33……×10-0.33……=3.33…-0.33……
(10-1) ×0.33……=3
即9×0.33……=3
那麼0.33……=3/9=1/3
由此可見, 純迴圈小數化分數,它的小數部分可以寫成這樣的分數:純迴圈小數的迴圈節最少位數是幾,分母就是由幾個9組成的數;分子是純迴圈小數中一個迴圈節組成的數。
⑵把0.4777……和0.325656……化成分數。
想1:0.4777……×10=4.777……①
0.4777……×100=47.77……②
用②-①即得:
0.4777……×90=47-4
所以, 0.4777……=43/90
想2:0.325656……×100=32.5656……①
0.325656……×10000=3256.56……②
用②-①即得:
0.325656……×9900=3256.5656……-32.5656……
0.325656……×9900=3256-32
所以, 0.325656……=3224/9900
將純迴圈小數改寫成分數,分子是一個迴圈節的數字組成的數;分母各位數字都是9,9的個數與迴圈節中的數字的個數相同.
將混迴圈小數改寫成分數,分子是不迴圈部分與第一個迴圈節連成的數字組成的數,減去不迴圈部分數字組成的數之差;分母的頭幾位數字是9,末幾位數字是0,9的個數跟迴圈節的數位相同,0的個數跟不迴圈部分的數位相同.
#include <cstdio> #include <algorithm> #include <cstring> //#define int long long using namespace std; int gcd(int a, int b){ while (b){ int tmp = a; a = b; b = tmp % b; } return a; } int n,j; int part1, part2, pow, sum_val, tmp_pow; char s[100]; int get_val(int &pos){ int ans = 0; while (s[pos] && s[pos] != '(' && s[pos] != ')'){ sum_val = sum_val *10 + s[pos] - '0'; ans = ans * 10 + s[pos++] - '0'; pow = pow * 10; } return ans; } void init(){ j = 2; sum_val = 0; pow = 1; part1 = part2 = sum_val = 0; part1 = get_val(j); tmp_pow = pow; if (s[j] == '(') ++j; part2 = get_val(j); } char c = '/'; int main(){ scanf("%d", &n); //getchar(); for (int i = 1; i <= n; ++i){ //gets(s); scanf("%s", s); init(); if (!part2){ int GCD = gcd(tmp_pow, sum_val); printf("%d%c%d\n", sum_val / GCD, c, tmp_pow / GCD); } else{ int fenmu = pow - tmp_pow; int fenzi; if (part1) fenzi = sum_val - part1; else fenzi = part2; int GCD = gcd(fenzi, fenmu); printf("%d%c%d\n", fenzi / GCD, c, fenmu / GCD); } } return 0; }