EOJ 2980. 小数转化分数

2980. 小数转化分数

题目:

给定一个正有理数A(A>0),输出 A的最简分数形式。

输入格式

第 1行:一个整数 T(1<=T<=10) 为问题数。

第2~T+1行:每行有一个字符串(字符串长度不超过),表示有理数。字符串中只包含三类字符:0~9,.,[,],在 [和 ] 之间的数字表示循环小数的循环节,例如:0.[6]表示有理数

输出格式

对于每个问题,输出一行问题的编号( 开始编号,格式:case #0: 等),然后在一行中输出 的最简分数形式,行末尾输出一个换行符。具体输出格式见样例。

样例

input

4
0.5
0.[6]
11.0[8]
1.[142857]

output

case #0:
1/2
case #1:
2/3
case #2:
499/45
case #3:
8/7

思路

无循环小数:gcd
纯循环小数:一个循环节有几个数,分母就有几个9,分子则为一个循环节上的数
例.0.[7]=7/9, 0.[114514]=114514/999999
混循环小数,循环节有几个数,分母就有几个9,不循环的有几个数,分母再添几个0,分子是从不循环到一个循环节数减去不循环的数
例.0.114[514]=(114514-114)/999000, 0.1[14514]=(114514-1)/999990

&
#include <iostream>
#include <string>
#include <algorithm>
using namespace std;
int main()
{
    int ti, ret = 0;
    cin >> ti;
    while (ti--)
    {
        printf("case #%d:\n", ret++);
        string a;
        string b;
        unsigned long long fenzi = 0, fenmu = 0;//终极杀器u64,让数据不再溢出
        cin >> a;
        int t = a.find('.');
        unsigned long long sumz = 0; //整数部分;
        for (int i = 0; i < t; i++)
        {
            sumz = sumz * 10 + (a[i] - '0');
        }
        int cl = a.find('['); //左括号
        int cr = a.find(']'); //右括号
        if (cl != -1)         //循环小数部分
        {
            if (cl - t == 1)
            {
                for (int i = cl + 1; i < cr; i++)
                {
                    fenzi = fenzi * 10 + (a[i] - '0');
                }
                int mo = cr - cl - 1;
                while (mo--)
                {
                    fenmu = fenmu * 10 + 9;
                }
            } //全段循环直接是循环段做分子,循环位个9做分母
            else
            {
                int po = cl - t - 1;
                int mo = cr - cl - 1;
                int temp = mo;
                while (mo--)
                {
                    fenmu = fenmu * 10 + 9;
                }

                for (int i = cl + 1; i < cr; i++)
                {
                    fenzi = fenzi * 10 + (a[i] - '0');
                }
                unsigned long long quan = 0;
                for (int i = t + 1; i < cl; i++)
                {
                    quan = quan * 10 + (a[i] - '0');
                }
                unsigned long long quan2 = quan;
                while (po--)
                {
                    fenmu *= 10;
                }
                while (temp--)
                {
                    quan2 *= 10;
                }
                // cout << fenzi << " " << quan << " " << quan2 << endl;
                fenzi = quan2 - quan + fenzi;
            }
            fenzi = fenzi + sumz * fenmu;
            long long tui = __gcd(fenzi, fenmu); //__gcd函数求最大公约数
            cout << fenzi / tui << "/" << fenmu / tui << endl;
        } //部分循环,前继段和循环段组成的数减去一份前继段组成数做分子,循环段长个9加前继段长个0做分母
        else
        {
            b.assign(a.rbegin(), a.rend());
            int thy = b.find('.');
            fenmu = 1;
            for (int i = t + 1; i < t + thy + 1; i++)
            {
                fenzi = fenzi * 10 + a[i] - '0';
            }
            while (thy--)
            {
                fenmu *= 10;
            }
            fenzi += sumz * fenmu;
           unsigned long long tui = __gcd(fenzi, fenmu); //__gcd函数求最大公约数
            cout << fenzi / tui << "/" << fenmu / tui << endl;
        }
    }
}
//总结:有了gcd,化简不是问题
//本人博客https://www.cnblogs.com/emokable/
//时间:2022/4/13
posted @ 2022-04-13 16:29  渣渣纸  阅读(128)  评论(0)    收藏  举报