這道題可以説是我目前刷到的patb組裏最麻煩的一道題
主要是帶分數這玩意已經記不清多少年都沒碰過了,而且各種情況非常容易考慮不全
最後靠自己也沒寫出個能全過的解,後來一看是數太大了而我全程都在用int的問題,可以説是百密一疏……
這裏附上柳神的心曠神怡的c++解法,註釋我寫的,然後後面的解析由chatglm4生成,方便理解。
#include <iostream>
#include <cmath>
using namespace std;
long long a, b, c, d;
// 計算兩個數的最大公約數
long long gcd(long long t1, long long t2)
{
return t2 == 0 ? t1 : gcd(t2, t1 % t2);
}
void func(long long m, long long n)
{
if (m * n == 0)
{
printf("%s", n == 0 ? "Inf" : "0");
return;
}
// 符號判斷
bool flag = ((m < 0 && n > 0) || (m > 0 && n < 0));
// 分數化簡運算時不考慮正負,先取絕對值!!
m = abs(m);
n = abs(n);
long long x = m / n; // 整數位
printf("%s", flag ? "(-" : "");
if (x != 0)
printf("%lld", x);
if (m % n == 0)
{ // 判斷是否只有整數
if (flag)
printf(")"); // 如果是負整數,則補全括號 (正整數沒括號)
return;
}
if (x != 0)
printf(" "); // x不為0,則輸出空格 (且整數的情況已在前面提前返回,不會運行到這)
m = m - x * n; // 真分子
long long t = gcd(m, n);
m = m / t;
n = n / t; // 約分成最簡分式
printf("%lld/%lld%s", m, n, flag ? ")" : "");
}
int main()
{
scanf("%lld/%lld %lld/%lld", &a, &b, &c, &d);
func(a, b);
printf(" + ");
func(c, d);
printf(" = ");
func(a * d + b * c, b * d);
printf("\n"); // a/b+c/d通分公式,輸出有理化後的結果
func(a, b);
printf(" - ");
func(c, d);
printf(" = ");
func(a * d - b * c, b * d);
printf("\n");
func(a, b);
printf(" * ");
func(c, d);
printf(" = ");
func(a * c, b * d);
printf("\n");
func(a, b);
printf(" / ");
func(c, d);
printf(" = ");
func(a * d, b * c);
return 0;
}
這段代碼是一個C++程序,用於處理分數的加減乘除運算,並且輸出結果。程序首先定義了一個計算最大公約數的函數gcd,然後定義了一個處理分數並格式化輸出的函數func。主函數main中讀取用户輸入的兩個分數,然後分別計算它們的和、差、積、商,並輸出結果。
程序使用scanf函數從標準輸入讀取兩個分數,格式為%lld/%lld %lld/%lld,分別對應四個長整型變量a, b, c, d。這裏的%lld是讀取長整型的格式指定符。
func函數是程序的核心,它接受兩個長整型參數m和n,分別代表分數的分子和分母。函數首先檢查分子或分母是否為0,如果是,則根據情況輸出Inf(無窮大)或0。接着,函數處理分數的正負號,並計算分數的整數部分x。然後,函數通過計算最大公約數來簡化分數,並按照格式輸出分數。
在main函數中,程序分別計算了兩個分數的和、差、積、商,並調用func函數輸出結果。加減運算通過通分後相加或相減來完成,乘法通過分子相乘、分母相乘來完成,除法則是通過分子乘以另一個分數的分母、分母乘以另一個分數的分子來完成。
程序的輸出格式化得很好,能夠處理正負整數和分數,以及它們的運算結果。