P1572 计算分数 题解

· · 题解

这道题是一道模拟题,但细节还是很多的。

首先我们要处理一下读入:可以直接 while(cin >> f1 >> a >> f2 >> b),其中 f1 是加/减号,f2 是分数线,a 是分子,b 是分母。注意第一个分数要单独读入。

然后我们就要处理一下计算的过程。由小学五年级数学知识可知:分母不同的两个分数相加,要先通分。形式化的,即:

\dfrac{a}{b} + \dfrac{c}{d} = \dfrac{a\times \operatorname{lcm}(b,d)\div b}{\operatorname{lcm}(b,d)} + \dfrac{c\times \operatorname{lcm}(b,d)\div d}{\operatorname{lcm}(b,d)}

我们可以写一个函数模拟这个过程。

然后我们就要按照同分母分数的计算方法来计算了。

计算完后要约分,不然可能会爆 int。即:

\dfrac{a}{b} = \dfrac{a \div \gcd(a, b)}{b\div \gcd(a, b)}

最后计算完之后还要再约分一次,不然在只有一个分数的情况下可能会出错。

输出也要特殊处理一下(以下记答案的分母和分子分别为 ansfmansfz):

在这里解释一下为什么对于负数的情况只要判断一种和不用判断分子为 0 的情况:

代码如下:(本代码可以通过目前讨论区的所有 hack 数据

#include <bits/stdc++.h>
using namespace std;
#define int long long

int fm, fz, ansfm, ansfz;
char a, b; 

int lcm(int a, int b){
    return a / __gcd(a, b) * b;
}

void tongfen(){
    int t = lcm(ansfm, fm);
    int anssum = t / ansfm;
    int sum = t / fm;
    ansfz *= anssum;
    ansfm *= anssum;
    fz *= sum;
    fm *= sum;
}

void yuefen(){
    int t = __gcd(ansfz, ansfm);
    ansfz /= t;
    ansfm /= t;
}

signed main(){
    cin >> ansfz >> b >> ansfm;
//  cout << ansfz << b << ansfm;
    while(cin >> a >> fz >> b >> fm){
//      cout << a << fz << b << fm;
//      cout << 1 << endl;
        tongfen();
        if(a == '+') ansfz += fz;
        else ansfz -= fz;
        yuefen();
    }
    yuefen();
    if(ansfm < 0) cout << -ansfz << "/" << -ansfm;
    else if(ansfm != 1) cout << ansfz << "/" << ansfm;
    else cout << ansfz;
    return 0;
}