题解 LGP8584 探索未知

由 hycqwq 发布

简化题面

问 $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


暂无评论

发表评论