Total Submission(s): 2206 Accepted Submission(s): 892
请你写一个程序不但可以将普通小数化成最简分数,也可以把循环小数化成最简分数。
每组数据只有一个纯小数,也就是整数部分为0。小数的位数不超过9位,循环部分用()括起来。
3 0.(4) 0.5 0.32(692307)
4/9 1/2 17/52
解题思路:读取普通小数及循环小数部分信息,根据数论公式化简就可以了,题目测试数据无刁钻数据(如0.0)。
数学公式:
n 表示普通小数位数,x 表示普通小数数值(化为整数)
m 表示循环小数位数,y 表示循环小数数值(化为整数)
既小数可表示为 0.x(y)
其原始分数为(x*(10^m-1)+y) / (10^n*(10^m-1))
只要求得分子分母最大公约数,将分子分母分别除公约数,即可得到最简分数,既题目答案。
#include<cstdio> #include<cstring> #include<algorithm> using namespace std; int main() { int b[10]; int i; int x,y; int n,m; int t; char a[20]; b[0]=1; for(i=1;i<10;i++) //分母出来辅助数组构建 b[i]=b[i-1]*10; scanf("%d",&t); while(t--) { scanf("%s",a); int str=strlen(a); for(i=0;i<str;i++) if(a[i]=='(') break; n=i-2; //普通小数部分位数 m=str-i-2; //循环小数部分位数 if(n>0&&m<=0) //只有普通小数部分,没有循环小数 { sscanf(a+2,"%d",&x); y=b[n]; } else if(m>0&&n<=0) //只有循环小数部分,没有普通小数 { sscanf(a+3,"%d",&x); y=b[m]-1; } else //既有循环小数部分,即有普通小数 { sscanf(a,"0.%d(%d)",&x,&y); x=x*(b[m]-1)+y; y=b[n]*(b[m]-1); } int j,k=1; i=x; j=y; while(k) //求最大公约数,用于分数化简 { if(i<j) swap(i,j); k=i%j; i=j; j=k; } printf("%d/%d\n",x/i,y/i); } return 0; }