HDU1717 小数化分数2

来源:互联网 发布:抱抱软件3.5 编辑:程序博客网 时间:2024/05/09 17:24

                                                        小数化分数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
30.(4)0.50.32(692307)
 

Sample Output
4/91/217/52
 

Source
2007省赛集训队练习赛(2)
 

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;}



原创粉丝点击