题目描述:
Ray 在数学课上听老师说,任何小数都能表示成分数的形式,他开始了化了起来,很快他就完成了,但他又想到一个问题,如何把一个循环小数化成分数呢?
请你写一个程序不但可以将普通小数化成最简分数,也可以把循环小数化成最简分数。
Input
第一行是一个整数N,表示有多少组数据。
每组数据只有一个纯小数,也就是整数部分为0。小数的位数不超过9位,循环部分用()括起来。
Output
对每一个对应的小数化成最简分数后输出,占一行。
Sample Input
3
0.(4)
0.5
0.32(692307)
Sample Output
4/9
1/2
17/52
分析:小数可分为有限小数、无限小数。有限小数化为分数很简单,小数点移到最右边得到的整数除以10的移动位数次方。如:0.5 5/10 1/2
无限小数可分为纯循环小数和混循环小数。
纯循环小数,以0.(3)示例
设0.(3)为x,则10x-x=3,即9x=3,所以x=1/3
再如,0.(23)
设0.(23)为x,则100x-x=23,即99x=23,所以x=23/99
总结:设小数为x,x*10^a-x=循环节部分变成的整数,其中a为循环节部分位数。
混循环小数,以0.32(692307)为例
设0.32(692307)为x,则10^8x-100x=32692307-32=32692275,所以x=32692275/(10^8-100)=17/52
总结:设小数为x,x*10^(a+b)-10^a*x=非循环节部分整数*10^b+循环节部分整数,其中a为使非循环节部分位数,b为循环节部分位数。
#include<bits/stdc++.h> #define ll long long using namespace std; ll gcd(ll a,ll b){ return b==0?a:gcd(b,a%b); } int main() { int t; cin>>t; while(t--){ string a; cin>>a; ll x=0,y=0,n=1,m=1,f=0; int len=a.length(); for(int i=2;i<len;i++){ if(f==0){ if(a[i]=='(') f=1; else{ x=x*10+(a[i]-'0'); n*=10; } } else{ if(a[i]==')') break; else{ y=y*10+(a[i]-'0'); m*=10; } } } //cout<<m<<endl; //普通小数 if(m==1){ ll g=gcd(x,n); x=x/g; n=n/g; cout<<x<<"/"<<n<<endl; }//纯循环小数 else if(n==1&&m!=1){ m=m-1; ll g=gcd(y,m); y=y/g; m=m/g; cout<<y<<"/"<<m<<endl; }//混循环小数 else if(n!=1&&m!=1){ //cout<<y<<endl; ll ard=n*m-n; x=(x*m+y)-x; ll g=gcd(ard,x); //cout<<ard<<" "<<x<<" "<<g<<endl; x=x/g; ard=ard/g; cout<<x<<"/"<<ard<<endl; } } return 0; }