小数化分数2

Time Limit: 1000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 2206    Accepted Submission(s): 892


Problem Description
Ray 在数学课上听老师说,任何小数都能表示成分数的形式,他开始了化了起来,很快他就完成了,但他又想到一个问题,如何把一个循环小数化成分数呢?
请你写一个程序不但可以将普通小数化成最简分数,也可以把循环小数化成最简分数。
 

Input
第一行是一个整数N,表示有多少组数据。
每组数据只有一个纯小数,也就是整数部分为0。小数的位数不超过9位,循环部分用()括起来。
 

Output
对每一个对应的小数化成最简分数后输出,占一行。
 

Sample Input
 
   
3 0.(4) 0.5 0.32(692307)
 

Sample Output
 
   
4/9 1/2 17/52
 

Source
 

Recommend
lcy

解题思路:读取普通小数及循环小数部分信息,根据数论公式化简就可以了,题目测试数据无刁钻数据(如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; }