1034 有理數四則運算 (20 分)
- 2019 年 10 月 5 日
- 筆記
1034 有理數四則運算 (20 分)
本題要求編寫程序,計算 2 個有理數的和、差、積、商。
輸入格式:
輸入在一行中按照 a1/b1 a2/b2
的格式給出兩個分數形式的有理數,其中分子和分母全是整型範圍內的整數,負號只可能出現在分子前,分母不為 0。
輸出格式:
分別在 4 行中按照 有理數1 運算符 有理數2 = 結果
的格式順序輸出 2 個有理數的和、差、積、商。注意輸出的每個有理數必須是該有理數的最簡形式 k a/b
,其中 k
是整數部分,a/b
是最簡分數部分;若為負數,則須加括號;若除法分母為 0,則輸出 Inf
。題目保證正確的輸出中沒有超過整型範圍的整數。
輸入樣例 1:
2/3 -4/2
輸出樣例 1:
2/3 + (-2) = (-1 1/3) 2/3 - (-2) = 2 2/3 2/3 * (-2) = (-1 1/3) 2/3 / (-2) = (-1/3)
輸入樣例 2:
5/3 0/6
輸出樣例 2:
1 2/3 + 0 = 1 2/3 1 2/3 - 0 = 1 2/3 1 2/3 * 0 = 0 1 2/3 / 0 = Inf
【我的代碼】
// 1034 有理數四則運算 (20 分).cpp : 此文件包含 "main" 函數。程序執行將在此處開始並結束。 // #include <iostream> #include <cstdio> using namespace std; //求最大公約數 int gcd(long long a, long long b) { return b == 0 ? a : gcd(b, a % b); } //打印一個數 void print(long long a_1, long long a_2) { long long b = 0; if (a_1 > 0) { //正數 if (a_2 == 1) cout << a_1; else if(a_1 > a_2){ //分子比分母大 b = a_1 / a_2; a_1 -= a_2 * b; cout << b << " " << a_1 << "/" << a_2; } else { //無需化簡 cout << a_1 << "/" << a_2; } } else if (a_1 == 0) { cout << 0; } else { //負數 if (a_2 == 1) cout << "(" << a_1 << ")"; else if (-1 * a_1 > a_2) { b = a_1 / a_2; a_1 = (-1 * a_1) % a_2; cout << "(" << b << " " << a_1 << "/" << a_2 << ")"; } else { //無需化簡 cout << "(" << a_1 << "/" << a_2 << ")"; } } } //減法 void sub(long long a_1, long long a_2, long long b_1, long long b_2) { print(a_1, a_2); cout << " " << "-" << " "; print(b_1, b_2); cout << " " << "=" << " ";; long long c_1 = a_1 * b_2 - a_2 * b_1; long long c_2 = a_2 * b_2; long long c = abs(gcd(c_1, c_2)); c_1 /= c; c_2 /= c; print(c_1, c_2); } //加法 void add(long long a_1, long long a_2, long long b_1, long long b_2) { print(a_1, a_2); cout << " " << "+" << " "; print(b_1, b_2); cout << " " << "=" << " ";; long long c_1 = a_1 * b_2 + a_2 * b_1; long long c_2 = a_2 * b_2; long long c = abs(gcd(c_1, c_2)); c_1 /= c; c_2 /= c; print(c_1, c_2); } //乘法 void mult(long long a_1, long long a_2, long long b_1, long long b_2) { print(a_1, a_2); cout << " " << "*" << " "; print(b_1, b_2); cout << " " << "=" << " ";; long long c_1 = a_1 * b_1; long long c_2 = a_2 * b_2; long long c = abs(gcd(c_1, c_2)); c_1 /= c; c_2 /= c; print(c_1, c_2); } //除法 void div(long long a_1, long long a_2, long long b_1, long long b_2) { print(a_1, a_2); cout << " " << "/" << " "; print(b_1, b_2); cout << " " << "=" << " "; if (!b_1) { cout << "Inf"; return; } else if (b_1 < 0) { long long c_1 = -1 * a_1 * b_2; long long c_2 = -1 * a_2 * b_1; long long c = abs(gcd(c_1, c_2)); c_1 /= c; c_2 /= c; print(c_1, c_2); } else { long long c_1 = a_1 * b_2; long long c_2 = a_2 * b_1; long long c = abs(gcd(c_1, c_2)); c_1 /= c; c_2 /= c; print(c_1, c_2); } } int main() { //輸入 long long a_1, a_2, b_1, b_2; scanf_s("%lld/%lld %lld/%lld", &a_1, &a_2, &b_1, &b_2); //把a,b化到最簡 long long num_1 = abs(gcd(a_1, a_2));//得到a的最大公約數 a_1 /= num_1; a_2 /= num_1; long long num_2 = abs(gcd(b_1, b_2));//得到b的最大公約數 b_1 /= num_2; b_2 /= num_2; //計算 add(a_1, a_2, b_1, b_2); cout << endl; sub(a_1, a_2, b_1, b_2); cout << endl; mult(a_1, a_2, b_1, b_2); cout << endl; div(a_1, a_2, b_1, b_2); return 0; }
【思路】
- 所有的數都要是化簡後的,因此需要單獨分離一個函數作為化簡函數,這裡參考了輾轉相除法,找到最大公約數,然後分子分母同時除最大共約數,得到最簡化的分式。
- 發現數字化簡到分式後還要化成分子比分母小的形式(忘記怎麼叫了),因此這裡需要一個格式轉換函數,就寫了一個print函數,對分子大於0,小於0和等於0進行討論。
- +、-、*都是直接對分子分母進行操作,這裡不需要考慮化簡問題,因為我們有單獨出來的化簡函數。而除法需要注意!!Inf的情況。