个人练习-PAT甲级-1088 Rational Arithmetic

题目链接https://pintia.cn/problem-sets/994805342720868352/problems/994805378443755520

不难,但是细节有些多要注意。

用到的分数类,分为整数部分、分子、分母

class Node {
public:
    long int part1, a, b;
};

首先写好输出函数,输入一个假分数,输出带分数,负数时要带括号。
(1)为零的话只需输出零,我们统一在带分数部分输出这个零,即整数部分为零的话不输出;
(2)仅有整数部分或仅有分数部分时空格不输出;
(3)符号在一开始就判断好

void Output(Node x) {
    bool isNeg = false;
    if (x.a < 0) {
        isNeg = true;
        x.a = -x.a;
        printf("(-");
    }

    Simplify(x);
    x.part1 = x.a / x.b;
    x.a -= x.b * x.part1;
    

    if (x.part1 != 0)
        printf("%ld", x.part1);
    if (x.part1 != 0 && x.a != 0)
        printf(" ");
    if (x.a == 0) {
        if (x.part1 == 0)
            printf("0");
    }
    else
        printf("%ld/%ld", x.a, x.b);
    
    if (isNeg)
        printf(")");
}

其中Simplify()函数是将分子分母约到最简,注意gcd()函数输入要都为正

void Simplify(Node& x) {
    long int tmp = gcd(abs(x.a), abs(x.b));
    x.a /= tmp;
    x.b /= tmp;
}

加减乘都不难,除法时要注意,要保持负号始终在分子的位置。

Node Divide(Node x, Node y) {
    Node ret;
    ret.a = x.a * y.b;
    ret.b = x.b * y.a;

    if (ret.a > 0 && ret.b < 0) {
        ret.b = -ret.b;
        ret.a = -ret.a;
    }
    else if (ret.a < 0 && ret.b < 0) {
        ret.b = -ret.b;
        ret.a = -ret.a;
    }
    else;

    return ret;
}

完整代码

#include <iostream>
#include<stdio.h>
#include<vector>
#include<algorithm>
#include<map>
#include<string.h>
#include<string>


using namespace std;

class Node {
public:
    long int part1, a, b;
};

long int gcd(long int a, long int b) {
    int tmp;
    if (a < b) {
        tmp = b;
        b = a;
        a = tmp;
    }
    while (b) {
        tmp = b;
        b = a % b;
        a = tmp;
    }
    return a;
}

void Change(Node& x, long int d) {
    x.a *= d;
    x.b *= d;
}

void Simplify(Node& x) {
    long int tmp = gcd(abs(x.a), abs(x.b));
    x.a /= tmp;
    x.b /= tmp;
}

void Output(Node x) {
    bool isNeg = false;
    if (x.a < 0) {
        isNeg = true;
        x.a = -x.a;
        printf("(-");
    }

    Simplify(x);
    x.part1 = x.a / x.b;
    x.a -= x.b * x.part1;
    

    if (x.part1 != 0)
        printf("%ld", x.part1);
    if (x.part1 != 0 && x.a != 0)
        printf(" ");
    if (x.a == 0) {
        if (x.part1 == 0)
            printf("0");
    }
    else
        printf("%ld/%ld", x.a, x.b);
    
    if (isNeg)
        printf(")");
}

Node Add(Node x, Node y) {
    long int new_de = x.b * y.b / gcd(x.b, y.b);
    Change(x, new_de / x.b);
    Change(y, new_de / y.b);
    Node ret;
    ret.b = new_de;
    ret.a = x.a + y.a;
    Simplify(ret);
    return ret;
}

Node Minus(Node x, Node y) {
    y.a = -y.a;
    return Add(x, y);
}

Node Product(Node x, Node y) {
    Node ret;
    ret.a = x.a * y.a;
    ret.b = x.b * y.b;
    return ret;
}

Node Divide(Node x, Node y) {
    Node ret;
    ret.a = x.a * y.b;
    ret.b = x.b * y.a;

    if (ret.a > 0 && ret.b < 0) {
        ret.b = -ret.b;
        ret.a = -ret.a;
    }
    else if (ret.a < 0 && ret.b < 0) {
        ret.b = -ret.b;
        ret.a = -ret.a;
    }
    else;

    return ret;
}

int main() {
    Node x, y, ret;
    scanf("%ld/%ld %ld/%ld", &x.a, &x.b, &y.a, &y.b);

    // Add
    ret = Add(x, y);
    Output(x);
    printf(" + ");
    Output(y);
    printf(" = ");
    Output(ret);
    printf("\n");

    // Minus
    ret = Minus(x, y);
    Output(x);
    printf(" - ");
    Output(y);
    printf(" = ");
    Output(ret);
    printf("\n");

    // Product
    ret = Product(x, y);
    Output(x);
    printf(" * ");
    Output(y);
    printf(" = ");
    Output(ret);
    printf("\n");

    // Divide
    ret = Divide(x, y);
    Output(x);
    printf(" / ");
    Output(y);
    printf(" = ");
    if (ret.b == 0)
        printf("Inf");
    else
        Output(ret);
    printf("\n");

    return 0;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值