题目大意
给定N个有理数,以分子/分母的形式,您应该计算它们的总和。
- 测试点4没有过去,后调试发现是自己寻找最大公因数的方法过于复杂,参考柳神代码,发现可以使用辗转相除来求解最大公因数。
- 辗转相除法
欧几里得算法又称辗转相除法,是指用于计算两个非负整数a,b的最大公约数。应用领域有数学和计算机两个方面。计算公式gcd(a,b) = gcd(b,a mod b)。
long long gcd(long long a, long long b){
return b == 0 ? abs(a) : gcd(b, a % b);
}
- y最后输出没有考虑为0的情况,测试点5最后折戟沉沙,加入最后的判断即可
if (res1 != 0) {
myprint(res1, res2);
}
else {
cout << '0';
}
代码实现
#include<bits/stdc++.h>
using namespace std;
int num;
vector<int> vec;
//最大公因数
long long gcd(long long a, long long b){
return b == 0 ? abs(a) : gcd(b, a % b);
}
void simpleRational(long long& r1, long long& r2) {
//分数的化简
int sign = 1;
if (r1 < 0) {
sign = -1;
r1 = r1 * -1;
}
int tem = min(r1, r2);
for (int i = tem; i >= 2; i--) {
if (r1 % i == 0 && r2 % i == 0) {
r1 = r1 / i;
r2 = r2 / i;
}
}
if (sign == -1)
r1 *= -1;
}
void sumRational(long long& r1, long long& r2, long long& R1, long long& R2) {
//分数相加,先通分,再相加
long long tem = r2;
r1 = r1 * R2;
r2 = r2 * R2;
R1 = R1 * tem;
R2 = R2 * tem;
r1 = r1 + R1;
long long vlue = gcd(r1, r2);
r1 /= vlue;
r2 /= vlue;
}
void myprint(long long& r1, long long r2) {
if (r1 < 0) {
cout << '-';
r1 *= -1;
}
if (r1 < r2) {
cout << r1 << '/' << r2;
}
else {
if (r1 % r2 == 0) {
cout << r1 / r2;
}
else {
cout << r1 / r2;
cout <<' '<< r1 % r2 << '/' << r2;
}
}
}
int main() {
cin >> num;
long long numerator;
long long denominator;
long long res1, res2;
long long value;
if (num >= 1)
scanf_s("%lld/%lld", &res1, &res2);
value =gcd(res1, res2);
res1 /= value;
res2 /= value;
for (int i = 1; i < num; i++) {
scanf_s("%lld/%lld", &numerator, &denominator);
value = gcd(numerator, denominator);
numerator /= value;
denominator /= value;
sumRational(res1, res2, numerator, denominator);
}
if (res1 != 0) {
myprint(res1, res2);
}
else {
cout << '0';
}
return 0;
}