HDU 1717 小数化分数2

来源:互联网 发布:淘宝退货怎么写小纸条 编辑:程序博客网 时间:2024/04/27 18:43

小数化分数2

                                                                Time Limit: 1000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)

                                                                                       Total Submission(s): 3040    Accepted Submission(s): 1239

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



题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1717


题目分析 :将该数分为两部分,即循环部分和非循环部分,最后答案为这两部分的和,设非循环部分的数字为num1

表示为分数结果是num1 / len1 (len1是num1的位数加1的基数)如0.32表示为32/100 循环部分则要用到等比数列求和。

设循环部分数字为num2,长度为len2 (len2是num2的位数加1的基数) 我们发现从小数点后的第k(k为基数的位数)位开始循环部分构成一个等比数列,

其首项为 num2/len2,公比为1/len2,根据等比数列求和公式Sn = a1(1-q^n)/(1-q),

这里q为1/len2显然len2>=10,因此当n趋向于无穷大的时候 (1/len2)^n趋向于0,

所以Sn = a1/(1-q) = num2 / (len2 - 1)要注意Sn是从小数点后第k位算起的所以Sn还要除以len1

两个分数想加 a/b + c/d = (ad + bc) / bd,所以要求分数为(num1 / len1) + num2 / ((len2 - 1) * len1)化简后为

(num1 * (len2 - 1) + num2) / (len1 * (len2 - 1)),最后求分子分母的最大公约数通下分就是答案。这里说的还只是有循环小数的情况

没循环小数的情况就直接取num1 / len1,再通下分即可


//思路见代码,程序实现很简单#include <cstdio>#include <cstring>int gcd(int a,int b){    return b == 0 ? a : gcd(b, a % b);}int main(){    int T, len, flag;    //nt1非循环部分分子  dt1非循环部分分母    //nt2循环部分分子,dt2循环部分分母    int nt1, nt2, dt1, dt2;    char str[50];    scanf("%d",&T);    while(T--)    {        flag = 1;        nt1 = nt2 = 0;        dt1 = dt2 = 1;        scanf("%s", str);        len = strlen(str);        for(int i = 2; i < len; i++)        {            if(str[i] == '(')            {                flag = 0;                continue;            }            if(str[i] >= '0' && str[i] <= '9')            {                if(flag)                {                    dt1 *= 10;                    nt1 = nt1 * 10 + str[i] - '0';                }                else                {                    dt2 *= 10;                    nt2 = nt2 * 10 + str[i] - '0';                }            }        }        if(flag)            printf("%d/%d\n", nt1 / gcd(nt1, dt1), dt1 / gcd(nt1, dt1));        else        {            int temp = gcd(nt1 * (dt2 - 1) + nt2  , dt1 * (dt2 - 1));            printf("%d/%d\n", (nt1 * (dt2 - 1) + nt2) / temp, dt1 * (dt2 - 1) / temp);        }    }}





0 0
原创粉丝点击