Skip to content

1034 有理数四则运算

Statement

Metadata

  • 作者: CHEN, Yue
  • 单位: 浙江大学
  • 代码长度限制: 16 KB
  • 时间限制: 200 ms
  • 内存限制: 64 MB

本题要求编写程序,计算 2 个有理数的和、差、积、商。

输入格式

输入在一行中按照 a1/b1 a2/b2 的格式给出两个分数形式的有理数,其中分子和分母全是整型范围内的整数,负号只可能出现在分子前,分母不为 0。

输出格式

分别在 4 行中按照 有理数1 运算符 有理数2 = 结果 的格式顺序输出 2 个有理数的和、差、积、商。注意输出的每个有理数必须是该有理数的最简形式 k a/b,其中 k 是整数部分,a/b 是最简分数部分;若为负数,则须加括号;若除法分母为 0,则输出 Inf。题目保证正确的输出中没有超过整型范围的整数。

输入样例 1

2/3 -4/2

输出样例 1

2/3 + (-2) = (-1 1/3)
2/3 - (-2) = 2 2/3
2/3 * (-2) = (-1 1/3)
2/3 / (-2) = (-1/3)

输入样例 2

5/3 0/6

输出样例 2

1 2/3 + 0 = 1 2/3
1 2/3 - 0 = 1 2/3
1 2/3 * 0 = 0
1 2/3 / 0 = Inf

Solution

#include <bits/stdc++.h>
using namespace std;
typedef long long LL;
LL gcd(LL x, LL y) {
    LL r;
    while (1) {
        r = x % y;
        if (!r)
            break;
        x = y;
        y = r;
    }
    return y;
}
struct pp {
    LL a = 0, b, total = 0;
} n1, n2, n11, n22;
pp tran(pp x) {
    LL num = gcd(x.a, x.b);
    if (num < 0)
        num *= -1;
    x.a /= num, x.b /= num;
    x.total += x.a / x.b;
    x.a %= x.b;
    if (x.a < 0 && x.total)
        x.a *= -1;
    return x;
}
void print(pp x) {
    if (x.total != 0 && x.a != 0) {
        if (x.total < 0)
            printf("(%d %d/%d)", x.total, x.a, x.b);
        else
            printf("%d %d/%d", x.total, x.a, x.b);
    } else if (x.a) {
        if (x.a < 0)
            printf("(%d/%d)", x.a, x.b);
        else
            printf("%d/%d", x.a, x.b);
    } else if (x.total) {
        if (x.total < 0)
            printf("(%d)", x.total);
        else
            printf("%d", x.total);
    } else
        printf("0");
}
pp pluss(pp x, pp y) {
    pp num;
    LL m = (x.b * y.b) / gcd(x.b, y.b);
    num.a = (x.a * (m / x.b) + y.a * (m / y.b)), num.b = m;
    num = tran(num);
    return num;
}
pp minuss(pp x, pp y) {
    if (y.total)
        y.total *= -1;
    else if (y.a)
        y.a *= -1;
    pp num = pluss(x, y);
    return num;
}
pp times(pp x, pp y) {
    pp num;
    if (x.a && y.a) {
        num.a = x.a * y.a;
        num.b = x.b * y.b;
    }
    num = tran(num);
    return num;
}
void paint(pp x, pp y, pp num, char c) {
    print(x);
    printf(" %c ", c);
    print(y);
    printf(" = ");
    print(num);
    cout << endl;
}
int main() {
    scanf("%lld/%lld %lld/%lld", &n1.a, &n1.b, &n2.a, &n2.b);
    n11 = tran(n1), n22 = tran(n2);
    if (n1.a)
        paint(n11, n22, pluss(n1, n2), '+');
    else {
        printf("0 + ");
        print(n22);
        printf(" = ");
        print(n22);
        cout << endl;
    }
    if (n1.a)
        paint(n11, n22, minuss(n1, n2), '-');
    else {
        printf("0 - ");
        print(n22);
        printf(" = ");
        pp temp = n2;
        temp.a *= -1;
        print(tran(temp));
        cout << endl;
    }
    if (n2.a && n1.a) {
        paint(n11, n22, times(n1, n2), '*');
    } else if (n1.a) {
        print(n11);
        printf(" * 0 = 0\n");
    } else {
        printf("0 * ");
        print(n22);
        printf(" = 0\n");
    }
    if (n2.a && n1.a) {
        if (n2.a < 0)
            n2.a *= -1, n2.b *= -1;
        swap(n2.a, n2.b);
        paint(n11, n22, times(n1, n2), '/');
    } else if (n1.a) {
        print(n11);
        printf(" / 0 = Inf\n");
    } else {
        printf("0 / ");
        print(n22);
        printf(" = 0\n");
    }
}

Last update: May 4, 2022
Back to top