日期:2025年7月25日
ZeroJudge 題目連結:b538. 分數運算-2
解題想法
這題比b537. 分數運算-1簡單很多,只要按照分數運算的規則,分別寫出加、減、乘、除的計算方式,再用 gcd 將分子、分母約分。輸出時分別三種:0、整除、分數,如果分母是負的,負號要加在分子的前面。
Python 程式碼
使用時間約為 19 ms,記憶體約為 3.4 MB,通過測試。
import sys, math
def fac_cal(a, b, c, d, op):
num, den = 1, 1 # 計算結果的分子、分母
if op == "+": # a/b + c/d = (a*d + c*b) / (b*d)
num = a*d + c*b
den = b*d
elif op == "-": # a/b - c/d = (a*d - c*b) / (b*d)
num = a*d - c*b
den = b*d
elif op == "*": # a/b * c/d = (a*c) / (b*d)
num = a*c
den = b*d
else: # a/b / c/d = a/b * d/c = (a*d) / (b*c)
num = a*d
den = b*c
if den < 0: # 如果分母小於 0,將分子、分母的正負號都反過來
num = -num; den = -den
g = math.gcd(num, den) # 取分子、分母最大公因數約分
num //= g; den //= g
if num == 0: return "0\n" # 分子為 0,回傳 0
elif num%den == 0: return f"{num:d}\n" # 可以整除,回傳分子
else: return f"{num:d}/{den:d}\n" # 不能整除
result = []
lines = sys.stdin.readlines()
for line in lines:
arr = line.split()
a, b, c, d = map(int, arr[:4]) # 分割出前 4 個數字
op = arr[-1] # 運算符號
result.append(fac_cal(a, b, c, d, op))
sys.stdout.write("".join(result))
使用時間約為 32 ms,記憶體約為 4.5 MB,通過測試。
import sys, fractions
result = []
lines = sys.stdin.readlines()
for line in lines:
arr = line.split()
a, b, c, d = map(int, arr[:4]) # 分割出前 4 個數字
op = arr[-1] # 運算符號
x = fractions.Fraction(a, b)
y = fractions.Fraction(c, d)
if op == '+': z = x + y
elif op == '-': z = x - y
elif op == '*': z = x * y
else: z = x / y
result.append(f"{z}\n")
sys.stdout.write("".join(result))
C++ 程式碼
使用時間約為 5 ms,記憶體約為 88 kB,通過測試。
#include <cstdio>
#include <algorithm>
using namespace std;
void fac_cal(int a, int b, int c, int d, char op) {
int num, den; // 計算結果的分子、分母
if (op == '+') { // a/b + c/d = (a*d + c*b) / (b*d)
num = a*d + c*b;
den = b*d;
} else if (op == '-') { // a/b - c/d = (a*d - c*b) / (b*d)
num = a*d - c*b;
den = b*d;
} else if (op == '*') { // a/b * c/d = (a*c) / (b*d)
num = a*c;
den = b*d;
} else { // a/b / c/d = a/b * d/c = (a*d) / (b*c)
num = a*d;
den = b*c;
}
int g = __gcd(num, den); // 取分子、分母最大公因數約分,這兩行要在第 22 ~ 24 行之前
num /= g; den /= g;
if (den < 0) { // 如果分母小於 0,將分子、分母的正負號都反過來
num = -num; den = -den;
}
if (num == 0) { // 分子為 0,印出 0
puts("0");
} else if (den == 1) { // 可以整除,印出分子
printf("%d\n", num);
} else { // 不能整除
printf("%d/%d\n", num, den);
}
}
int main() {
int a, b, c, d; // 前 4 個整數
char op; // 運算符號
while(scanf("%d %d %d %d %c", &a, &b, &c, &d, &op) != EOF) {
fac_cal(a, b, c, d, op);
}
return 0;
}
使用時間約為 2 ms,記憶體約為 100 kB,通過測試。
#include <cstdio>
#include <algorithm>
using namespace std;
void fac_cal(int a, int b, int c, int d, char op) {
int num, den; // 計算結果的分子、分母
switch (op) {
case '+': // a/b + c/d = (a*d + c*b) / (b*d)
num = a*d + c*b;
den = b*d;
break;
case '-': // a/b - c/d = (a*d - c*b) / (b*d)
num = a*d - c*b;
den = b*d;
break;
case '*': // a/b * c/d = (a*c) / (b*d)
num = a*c;
den = b*d;
break;
default: // a/b / c/d = a/b * d/c = (a*d) / (b*c)
num = a*d;
den = b*c;
}
int g = __gcd(num, den); // 取分子、分母最大公因數約分,這兩行要在第 22 ~ 24 行之前
num /= g; den /= g;
if (den < 0) { // 如果分母小於 0,將分子、分母的正負號都反過來
num = -num; den = -den;
}
if (num == 0) { // 分子為 0,印出 0
puts("0");
} else if (den == 1) { // 可以整除,印出分子
printf("%d\n", num);
} else { // 不能整除
printf("%d/%d\n", num, den);
}
}
int main() {
int a, b, c, d; // 前 4 個整數
char op; // 運算符號
while(scanf("%d %d %d %d %c", &a, &b, &c, &d, &op) != EOF) {
fac_cal(a, b, c, d, op);
}
return 0;
}
沒有留言:
張貼留言