分數四則運算(結構體版)

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 你的程式,然後:

  1. 讀入 \(Q\)。
  2. 對每筆詢問 a b op c d,宣告 Fraction x(a, b), y(c, d);,並檢查兩者都是最簡分數且分母為正。不是的話,印出一行 [檢查] Fraction(a, b) 建構後必須是最簡分數且分母為正 之後直接結束(結果會是 Wrong Answer;用「測試範例」跑就看得到這行訊息)。
  3. op 是 =:印出 x == y ? 1 : 0。
  4. 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。

題目頁說明

快速鍵

主要功能

  • 範例測試 — 執行題目附帶的範例測資並自動比對預期輸出。
  • 自訂測試 — 自己貼 stdin 執行程式。可勾選「與預期輸出比對 (diff)」做行對行比對。
  • 模板 — 貼上你在個人資料設定的預設程式碼模板。
  • 協作 — 與其他同學共筆編輯這題的程式碼。
  • 自動草稿 — 編輯器內容每 1.5 秒自動存到瀏覽器(per 帳號 / 題目 / 語言)。
  • 提交 — 把程式碼交給 judge 評測,回傳 AC / WA / TLE 等結果。

限制

  • 程式碼最多 65,536 字元
  • 自訂測試 stdin 與預期輸出各最多 1 MB (約 100 萬字元)
  • 自訂測試與範例測試共用一個沙箱,每人約 3 秒 1 次 (範例測試 1 秒 1 次)
  • 自訂測試與範例測試都有 15 秒 牆鐘上限(正式評測仍依題目原本時限)
  • 互動題不提供自訂測試(無法模擬與 judge 互動)。
  • 提交評測本身沒有 rate limit,但同題短時間內多次提交會被視為刷分。