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

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

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

题目分析

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

注意点

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

我的解题过程

思路

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

bug

  1. 输出真分母的时候,中间的空格问题,有时候输出完实数部分后,后面就没有分母形式了,此时就不需要输出空格(所幸这点可以通过测试用例发现,不然估计自己找也够呛),可以采用flag标记一下是否输出了实数部分然后在输出分数部分前check一下,如果输出过则输出一个空格
  2. 还是输出函数的问题,输出为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. 如果答案只需要输出实数部分的话,那么结果的分母一定为1,可以通过这个直接输出分子后结束而不需要考虑空格问题,还可以解决0的输出问题
  2. 本题采用scanf的格式化输入会十分方便,直接得到了分子分母
scanf("%lld/%lld", &a, &b);
  1. 本题参考晴神的代码比较好,虽然思想一样,但是模板可移植性更高
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值