【PAT甲级】1081 Rational Sum (20分)

    技术2025-09-12  87

    解题过程的小记录,如有错误欢迎指出。

    难度:三星(分数的加法运算,化简步骤涉及了求两数的最大公约数,以及分数的表达规则要记住,此处多复习算法笔记的相关篇章)

    小导航~

    题目分析注意点 我的解题过程思路bug代码 dalao的代码借鉴点

    题目分析

    给出一串分数,要求求出它们的和并按照指定格式输出

    注意点

    测试当输出为0的时候能否正常输出采用long long存储分子分母数据找最大公约数的时候注意两个数字都必须转换为绝对值,不然后续的除法化简会因为符号问题出错(如INPUT:2 1/2 -1/3答案应为-1/6)【但是本题的测试点好像没有涉及这一点,我原来没有考虑这一点,也过了,看了晴神的解析才发觉】

    我的解题过程

    思路

    输入分数,采用了以string格式输入后找到’/'后用substr进行拆分利用stoll进行转换的方法,进行输入初始化result为一个为0的分数(分子为0,分母为1),在输入后进行化简,直接进行累加写一个累加函数,利用数学公式写出分子分母的变化,返回前进行化简写一个化简函数,其中要用到最大公约数函数写一个输出函数

    bug

    输出真分母的时候,中间的空格问题,有时候输出完实数部分后,后面就没有分母形式了,此时就不需要输出空格(所幸这点可以通过测试用例发现,不然估计自己找也够呛),可以采用flag标记一下是否输出了实数部分然后在输出分数部分前check一下,如果输出过则输出一个空格还是输出函数的问题,输出为0/1的时候,原函数的逻辑下不输出,后来增加了一个if判断分子是否为0,如果是的话直接输出0后返回

    代码

    #include<iostream> #include<string> #include<algorithm> using namespace std; typedef long long LL; struct Fenshu { LL up, down;//分子分母:如果为0,则up=0,down=1,如果为负则up<0,down>0 }; LL gcd(LL a, LL b) { a = abs(a); b = abs(b); return b == 0 ? a : gcd(b, a%b); } Fenshu reduction(Fenshu f) { if (f.up == 0 || f.down == 0) f.up = 0, f.down = 1; else if (f.up / f.down < 0) f.up = -abs(f.up), f.down = abs(f.down); LL g = gcd(f.up, f.down); f.up = f.up / g; f.down = f.down / g; return f; } Fenshu addFenshu(Fenshu f1, Fenshu f2) { Fenshu ans; ans.up = f1.up*f2.down + f2.up*f1.down; ans.down = f1.down*f2.down; return reduction(ans); } void prit(Fenshu f) { if (f.up == 0) { cout << 0; return; } int flag = 0; if (abs(f.up) > f.down) { cout << f.up / f.down; flag = 1; } if (f.up%f.down != 0) { if (flag == 1) cout << " "; cout << f.up%f.down << "/" << f.down; } } int main() { int n; cin >> n; Fenshu result; result.up = 0, result.down = 1; for (int i = 0; i < n; i++) { Fenshu f; string s; int pos = 0; cin >> s; while (s[pos] != '/') pos++; f.up = stoll(s.substr(0, pos)); f.down = stoll(s.substr(pos + 1)); result = addFenshu(result, reduction(f)); } prit(result); return 0; }

    dalao的代码

    全部代码因版权原因不放出来,大家可以自行去柳神博客购买或者参考晴神的上机笔记~

    借鉴点

    如果答案只需要输出实数部分的话,那么结果的分母一定为1,可以通过这个直接输出分子后结束而不需要考虑空格问题,还可以解决0的输出问题本题采用scanf的格式化输入会十分方便,直接得到了分子分母 scanf("%lld/%lld", &a, &b); 本题参考晴神的代码比较好,虽然思想一样,但是模板可移植性更高
    Processed: 0.014, SQL: 9