PAT_1081 Rational Sum (20 分)

博客内容涉及编程算法,主要讨论如何处理分数序列的通分与约分问题。作者通过实例分析了在处理负数时可能出现的问题,并提出了解决方案,即转换为正数进行求最大公约数以避免负数导致的错误。代码实现中使用了最小公倍数、最大公约数等数学概念,最终能够正确处理各种输入并输出期望结果。
摘要由CSDN通过智能技术生成

题目链接
思路很简单,先求所有分母的最小公倍数,即通分后分子相加,common就是最小公倍数,也是通分后的分母,获取整数部分resint=resa/common,获取分数部分的分子resa=resa%common,分母就是common,还需要进行约分,首先需要求分子分母的最大公约数,要注意分子为0时不能用gcd求最大公约数,因为用gcd辗转相除用到较小数当分母,而分母不能为0.

开始写的代码在pta练习集提交满分,但是在牛客网上对于下面的样例我的程序错误输出了1/-3,发现求-1和3的最大公约数时,因为3%-1=0,会返回的最大公约数是-1,这样-1/3就变成了1/-3,既然约分时用到的最大公约数对正负号无影响,所以传递参数时可以都传正数,就过了所有样例了。

输入: 2 -2/3 1/3
正确输出:-1/3

还有要注意的是long long的变量scanf读入时需要格式为%lld
有时间再学习一下带负数的取模运算机制,待补充······

·
·
·
·
·

完整代码:

#include <iostream>
#include <cstdio>
typedef long long ll;
using namespace std;
ll gcd(ll a,ll b);
int main() {
    ll a[101],b[101];
    ll N;
    cin >> N;
    ll common;//储存分母的最小公倍数
    for(ll i=1;i<=N;i++){
        scanf("%lld/%lld",&a[i],&b[i]);//lld
    }
    common=b[1];
    for(ll i=2;i<=N;i++){
        ll g=gcd(common,b[i]);
        common=common*b[i]/g;
    }

    ll resint=0,resa=0,resb=0;
    for(ll i=1;i<=N;i++){
        resa+=common/b[i]*a[i];
    }

    resint=resa/common;
    resa=resa%common;
    if(resa!=0){//分子不为0才有约分的必要
        ll tmpa=gcd(max(resa,-resa),common);
        resa/=tmpa;
        resb=common/tmpa;
    }
    if(resint==0 && resa!=0) {
        printf("%d/%d",resa,resb);
    }
    else if(resa==0) cout << resint;
    else{
        cout << resint << " ";
        printf("%d/%d",resa,resb);
    }

    return 0;
}
ll gcd(ll a,ll b){
    ll big=max(a,b);
    ll small=min(a,b);

    ll yu=big%small;

    while(yu!=0){
        big=small;
        small=yu;
        yu=big%small;
    }
    return small;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值