EOJ 2980. 小數轉化分數
阿新 • • 發佈:2022-04-13
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