zoukankan      html  css  js  c++  java
  • ACM学习历程—HDU1717 小数化分数2(gcd)

    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

    假如设小数点后的整数记为val1,括号里循环的整数记为val2。

    val1的位数记为len1,val2的位数记为len2。

    记小数的不循环部分是e1, 循环部分是e2.

    对于e2 * 10^len1这个小数t:

    必然t * 10^len2 - val2 = t;

    自然t = val2 / (10^len2 - 1)

    e2 = val2 / (10^len2 - 1) / 10^len1;

    然后e1 = val1 / 10^len1;

    所以整个小数就是e1 + e2;

    然后对分子分母同分一下,最后分子分母再同除最小公倍数即可。

    需要注意的是要对len2等于0的情况特判一下。

    代码:

    #include <iostream>
    #include <cstdio>
    #include <cstdlib>
    #include <cstring>
    #include <cmath>
    #include <algorithm>
    #include <set>
    #include <map>
    #include <vector>
    #include <queue>
    #include <string>
    #define LL long long
    
    using namespace std;
    
    LL e[11], val1, val2, A, B;
    int len1, len2;
    char str[50];
    
    void Init()
    {
        e[0] = 1;
        for (int i = 1; i < 11; ++i)
        {
            e[i] = 10*e[i-1];
        }
    }
    
    void Input()
    {
        scanf("%s", str);
        len1 = len2 = 0;
        val1 = val2 = 0;
        for (int i = 2; str[i] != ''; ++i)
        {
            if (str[i] == '(')
            {
                for (int j = i+1; str[j] != ')'; ++j)
                {
                    val2 = 10*val2 + str[j] - '0';
                    len2++;
                }
                break;
            }
            val1 = 10*val1 + str[i] - '0';
            len1++;
        }
        if (len2)
        {
            A = val1*(e[len2] - 1) + val2;
            B = e[len1] * (e[len2]-1);
        }
        else
        {
            A = val1;
            B = e[len1];
        }
    }
    
    LL gcd(LL a, LL b)
    {
        if (b == 0)
            return a;
        else
            return gcd(b, a%b);
    }
    
    void Work()
    {
        LL d = gcd(A, B);
        A /= d;
        B /= d;
        printf("%I64d/%I64d
    ", A, B);
    }
    
    int main()
    {
        //freopen("test.in", "r", stdin);
        int T;
        scanf("%d", &T);
        Init();
        for (int times = 0; times < T; ++times)
        {
            Input();
            Work();
        }
        return 0;
    }
  • 相关阅读:
    迭代器模式 -- 大话设计模式
    组合模式 -- 大话设计模式
    备忘录模式 -- 大话设计模式
    totalcmd简单教程--help详解
    Listary Primary
    Cygwin Primary
    Google calendar
    极点郑码标点符号
    Totalcmd 简单教程
    Foobar 简单教程
  • 原文地址:https://www.cnblogs.com/andyqsmart/p/4526527.html
Copyright © 2011-2022 走看看