1. 程式人生 > 其它 >EOJ 2980. 小數轉化分數

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