首页 > 代码库 > HDU 1717 小数化分数2

HDU 1717 小数化分数2

小数化分数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);
        }
    }
}