hdu 1717小數化分數2
眾所周知,有限小數是十進分數的另一種表現形式,因此,任何一個有限小數都可以直接寫成十分之幾、百分之幾、千分之幾……的數。那麼無限小數能否化成分數?
首先我們要明確,無限小數可按照小數部分是否迴圈分成兩類:無限迴圈小數和無限不迴圈小數。無限不迴圈小數不能化分數,這在中學將會得到詳盡的解釋;無限迴圈小數是可以化成分數的。那麼,無限迴圈小數又是如何化分數的呢?由於它的小數部分位數是無限的,顯然不可能寫成十分之幾、百分之幾、千分之幾……的數。其實,迴圈小數化分數難就難在無限的小數位數。所以我就從這裡入手,想辦法“剪掉”無限迴圈小數的“大尾巴”。策略就是用擴倍的方法,把無限迴圈小數擴大十倍、一百倍或一千倍……使擴大後的無限迴圈小數與原無限迴圈小數的“大尾巴”完全相同,然後這兩個數相減,“大尾巴”不就剪掉了嗎!我們來看兩個例子:
⑴ 把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 <iostream> #include <cstdio> #include <cmath> #include <cstring> using namespace std; int t; char s[15]; int s1,s2,l1,l2,p,q; int gcd(int a,int b) { int c; if(a==0) return b; while(b) { c=b;b=a%b;a=c; } return a; } int main() { scanf("%d",&t); while(t--) { scanf("%s",s); int len=strlen(s); s1=s2=l1=l2=0; int i=2; while(i<len&&s[i]!='(') { s1*=10; s1+=s[i]-'0'; l1++; i++; } i++; while(i<len&&s[i]!=')') { s2*=10; s2+=s[i]-'0'; l2++; i++; } //cout<<s1<<" "<<s2<<" "<<l1<<" "<<l2<<endl; if(l2==0) //有限小數 { p=s1; q=pow(10,l1); } else //無限小數 { p=s1*pow(10,l2)+s2-s1; q=(pow(10,l2)-1)*pow(10,l1); } int gc=gcd(p,q); p/=gc; q/=gc; printf("%d/%d\n",p,q); } return 0; }