分數四則運算(結構體版)
0.5s 256M這題是〔分數比大小(結構體版)〕的續集:同一個 Fraction,再教它加、減、乘、除與判斷相等——14.7 算術運算子多載的主戰場。
請定義結構體 Fraction,用兩個 long long 成員 p(分子)、q(分母)表示分數 \(\frac{p}{q}\),並且隨時保持最簡分數、分母為正(例如 \(\frac{4}{-8}\) 存起來必須是 p = -1、q = 2;\(0\) 一律存成 p = 0、q = 1)。成員的名稱、型態與簽名都必須完全一樣:
| 成員 | 型態/簽名 | 意義 |
|---|---|---|
p |
long long |
分子 |
q |
long long |
分母(永遠是正的) |
Fraction() |
建構子 | 無參數:分數為 \(0\),也就是 p = 0、q = 1 |
Fraction(long long a, long long b) |
建構子 | 表示 \(\frac{a}{b}\)(\(b \ne 0\),可能是負的):建構完必須已經約分、分母為正 |
void print() |
成員函式 | 印出 p/q 並換行;q = 1 也要印 /1(例如 5/1、0/1) |
bool operator < (const Fraction &b) const |
成員函式 | 自己是否小於 b |
bool operator == (const Fraction &b) const |
成員函式 | 自己是否等於 b |
Fraction operator + (const Fraction &b) const |
成員函式 | 回傳「自己加 b」的新分數,不改動自己 |
Fraction operator - (const Fraction &b) const |
成員函式 | 回傳「自己減 b」的新分數 |
Fraction operator * (const Fraction &b) const |
成員函式 | 回傳「自己乘 b」的新分數 |
Fraction operator / (const Fraction &b) const |
成員函式 | 回傳「自己除以 b」的新分數(保證 b 不是 \(0\)) |
四則運算回傳的分數同樣必須是最簡分數、分母為正——把算好的分子分母交給建構子 Fraction(分子, 分母),它就會自動約分。
你只需要寫這個結構體的定義,不用寫 main、不用 #include 任何東西——評測程式會自動在你的程式最上方加上這題需要的標頭(<iostream>、<numeric>)與 using namespace std;,要用其他標頭自己再 #include 即可(所以 gcd、cout 能直接用)。想把含有 main 的完整程式貼上來測試也可以,評測時會忽略你的 main。
可以直接複製下面的骨架來改:
struct Fraction {
long long p; // 分子
long long q; // 分母(保持為正)
Fraction(long long a = 0, long long b = 1) {
// 把 a/b 存進來,化成最簡分數、分母為正
}
void print() {
// 印出 p/q 並換行
}
bool operator < (const Fraction &b) const {
// 分母都是正的:交叉相乘
}
bool operator == (const Fraction &b) const {
// 都是最簡分數:比對成員
}
Fraction operator + (const Fraction &b) const {
// 通分後相加,交給建構子約分
}
// 再補上 -、*、/
};
評測程式會做的事
評測程式會 #include 你的程式,然後:
- 讀入 \(Q\)。
- 對每筆詢問
a b op c d,宣告Fraction x(a, b), y(c, d);,並檢查兩者都是最簡分數且分母為正。不是的話,印出一行[檢查] Fraction(a, b) 建構後必須是最簡分數且分母為正之後直接結束(結果會是 Wrong Answer;用「測試範例」跑就看得到這行訊息)。 op是=:印出x == y ? 1 : 0。op是+、-、*、/:執行Fraction z = x op y;,檢查z是最簡分數且分母為正(不是的話印出[檢查] x op y 的結果必須是最簡分數且分母為正之後直接結束),然後呼叫z.print()。
四則運算都是在 const 的 x、y 上呼叫的:運算子必須是 const 成員函式、回傳新的一包;改動自己的寫法會直接編譯失敗。若不符合規格,編譯訊息的第一行會告訴你缺了什麼,例如 [檢查] Fraction 的 operator + 必須回傳 Fraction(回傳新的一包,不要回傳 void)。
輸入格式
(這是評測程式讀的輸入。)第一行有一個整數 \(Q\),代表詢問數量。接下來 \(Q\) 行,每行 a b op c d:兩個整數 \(a, b\)、一個字元 op、兩個整數 \(c, d\),以空白分隔,代表計算 \(\frac{a}{b}\) op \(\frac{c}{d}\);op 是 +、-、*、/、= 之一。
限制
- \(1 \le Q \le 10^4\)
- \(-10^9 \le a, c \le 10^9\)
- \(-10^9 \le b, d \le 10^9\),且 \(b \ne 0\)、\(d \ne 0\)(分母可能是負的)
op是/時,\(c \ne 0\)- 在這個範圍內,通分與交叉相乘的每個乘積都不超過 \(10^{18}\)、相加不超過 \(2 \times 10^{18}\),用
long long計算不會溢位
輸出格式
對每筆詢問輸出一行:op 是 +、-、*、/ 時印出結果的最簡分數 p/q(分母為正;分母是 \(1\) 也要印 /1);op 是 = 時,兩個分數相等印 1,否則印 0。
範例輸入 1
7
1 2 + 1 3
1 2 - 1 2
2 3 * 3 4
1 2 / -3 4
-1 -2 = 2 4
1 3 = 2 3
5 1 + 0 7
範例輸出 1
5/6
0/1
1/2
-2/3
1
0
5/1
範例解釋 1
- 第 \(2\) 筆:\(\frac{1}{2} - \frac{1}{2} = 0\),印成
0/1。 - 第 \(3\) 筆:\(\frac{2}{3} \times \frac{3}{4} = \frac{6}{12}\),約分成 \(\frac{1}{2}\)。
- 第 \(4\) 筆:\(\frac{1}{2} \div \frac{-3}{4} = \frac{1}{2} \times \frac{4}{-3} = \frac{4}{-6}\),約分並把分母翻正後是 \(\frac{-2}{3}\)。
- 第 \(5\) 筆:\(\frac{-1}{-2}\) 與 \(\frac{2}{4}\) 建構後都是
p = 1、q = 2,相等。 - 第 \(7\) 筆:\(\frac{5}{1} + \frac{0}{7} = \frac{35}{7} = \frac{5}{1}\),分母是 \(1\) 也要印
/1。