(PAT甲)1081 Rational Sum

这道题是一道求输入分数之和的题,可能有负数。如果答案为假分数,则要按照带分数的形式输出,整数则按照整数输出,否则按照真分数输出。

注:

  1. 负数无需特殊处理,只需要当作分子为负数的分数即可
  2. 数据范围为int,两个分母相乘时,最大可以达到long long,所以如果使用int会溢出,得到“error”
  3. 计算最大公约数时,注意分子分母绝对值的公约数,否则数据会错误 
  4. 且必须在每一步加法后均进行约分,否则若等全部加完后才进行约分就会溢出
#include<iostream>
#include<algorithm>
using namespace std;
typedef long long l;

l gys(l a, l b)
{
	return b == 0 ? a : gys(b, a % b);
}

struct fraction
{
	l numerator, denominator;//分子,分母
};

fraction reduc(fraction result)//化简
{
	if (result.denominator < 0)//分母为负数,令分子和分母都变为相反数
	{
		result.numerator = -result.numerator;
		result.denominator = -result.denominator;
	}
	if (result.numerator == 0)
	{
		result.denominator = 1;
	}
	else
	{
		l d = gys(abs(result.numerator), abs(result.denominator));
		result.numerator /= d;
		result.denominator /= d;
	}
	return result;
}

fraction add(fraction f1, fraction f2)//分数f1与分数f2相加
{
	fraction result;
	result.numerator = f1.numerator * f2.denominator + f2.numerator * f1.denominator;//分数和的分子
	result.denominator = f1.denominator * f2.denominator;//分数和的分母
	return reduc(result);
}

void showresult(fraction r)
{
	reduc(r);
	if (r.denominator == 1)
		cout << r.numerator << endl;//输出整数
	else if (abs(r.numerator) > r.denominator)
	{
		printf("%lld %lld/%lld\n", r.numerator / r.denominator, abs(r.numerator) % r.denominator, r.denominator);
	}
	else
	{
		printf("%lld/%lld\n", r.numerator, r.denominator);
	}
}

int main()
{
	int n;
	cin >> n;
	fraction sum, temp;
	sum.numerator = 0;
	sum.denominator = 1;
	for (int i = 0; i < n; i++)
	{
		scanf("%lld/%lld", &temp.numerator, &temp.denominator);
		sum = add(sum, temp);
	}
	showresult(sum);
	return 0;
}

这里使用的是scanf,vs上可以使用scanf_s避免溢出,scanf在很多编译器上已经淘汰,但是在pat上还可以使用,如果使用cin,我不知道怎么处理表达式的关系,若每个表达式均用一个变量赋值后再输入输出未免太过冗余,待以后学习后再来优化。

以下是测试结果:

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值