简化题面
问 $n$ 个分数之和,其中有正有负。
思路
利用“减一个数等于减它的相反数”把减法转换为加法。
然后就是通分,相加再约分。
具体实现方法
- 通分:两个分数都上下同乘另一个分数的分母,注意要把先乘的分数的分母存起来。
- 相加:分子相加,没得说。
- 约分:分数上下同除分子与分母的最大公因数(即 gcd),注意也要把 gcd 存起来,因为原分数会改变。
代码
易错点:这个数据范围要开 long long,血与泪的教训。
#include <iostream>
#include <algorithm>
using namespace std;
typedef long long ll;
ll gcd(ll x, ll y)//辗转相除法求最大公因数
{
if (y == 0)//原y为x的倍数
return x;//即gcd为x
return gcd(y, x % y);//取余继续除
}
int main()
{
ll n, x = 0, y = 1;//x分子,y分母,0/1为0,注意:分母不能为0
cin >> n;
for (ll i = 1, a, b, opt, t; i <= n; i++)//t为临时变量
{
cin >> a >> b >> opt;//a分子,b分母
if (opt == 2)//如果是减法
a = -a;//减一个数等于加它的相反数
#ifndef ONLINE_JUDGE//调试
cout << x << "/" << y << " + " << a << "/" << b << " = ";
#endif
//先通分
t = y;//因为后面会动,所以要存,切记!
y *= b, x *= b;//原分数x/y变为xb/yb
b *= t, a *= t;//原分数a/b变为ay/by
//再相加
x += a;
#ifndef ONLINE_JUDGE//调试
cout << x << "/" << y << " = ";
#endif
//最后约分
t = gcd(x, y);//因为约分过程中x和y会变,所以先存一下
x /= t, y /= t;
#ifndef ONLINE_JUDGE//调试
cout << x << "/" << y << " gcd:" << t << endl;
#endif
}
if (y < 0)//特判:如果分母为负
x = -x, y = -y;//上下同乘-1
cout << x;//正负号包含在x中,因为分母为正数
if (y != 1)//分母为1即为正数,不用输出分母,只有分母不是1时才输出分母
cout << "/" << y;//别忘了斜杠
cout << endl;//个人习惯
return 0;
}
评测记录:R90497939。