1081 Rational Sum (20 分)

Given N rational numbers in the form numerator/denominator, you are supposed to calculate their sum.

Input Specification:
Each input file contains one test case. Each case starts with a positive integer N (≤100), followed in the next line N rational numbers a1/b1 a2/b2 … where all the numerators and denominators are in the range of long int. If there is a negative number, then the sign must appear in front of the numerator.

Output Specification:
For each test case, output the sum in the simplest form integer numerator/denominator where integer is the integer part of the sum, numerator < denominator, and the numerator and the denominator have no common factor. You must output only the fractional part if the integer part is 0.

Sample Input 1:
5
2/5 4/15 1/30 -2/60 8/3
Sample Output 1:
3 1/3
Sample Input 2:
2
4/3 2/3
Sample Output 2:
2
Sample Input 3:
3
1/3 -1/6 1/8
Sample Output 3:
7/24

总结:注意细节!!!
注意事项:当整数部分和小数部分都为0,整数部分为0,小数分子部分为0 三种特殊情况。
算法:欧几里得求公约数和公倍数的性质

// 最小公倍数=两个数的乘积/最大公约数
// 最大公约数求法,欧几里得公式 
// fractional part 分数部分
// 分子部分 整数都可以先进行消除 
#include <iostream>
#include <cstring>
#include <algorithm>
#include <vector>
using namespace std;
typedef long long ll;
struct node{
	ll fz;
	ll fm;
}cap[200];
ll n;
ll gcd(ll a,ll b)
{
	if(b==0) return a;
	return gcd(b,a%b);
}
ll sum = 0;
int main()
{
	cin>>n;
	for(int i =0;i<n;i++)
	{
		scanf("%lld/%lld",&cap[i].fz,&cap[i].fm);
		sum+=(cap[i].fz/cap[i].fm); //取整数 
		cap[i].fz %= cap[i].fm; //加法的话将整数去掉 
	}
	node res;
	res.fz = cap[0].fz;
	res.fm = cap[0].fm;
	int flag;       //记录负号 
	for(int i =1;i<n;i++)
	{
		flag = 0;
		ll u = res.fm;       //只需要让分母一直保持正数就可以了 
		ll v = cap[i].fm;
		//将大的变在前面
		if(v==0)
		{
			continue;
		}
		if(u<v) swap(u,v); 
		ll gy = gcd(u,v);
		ll gb = u*v/gy;
		
		res.fz *=(gb/res.fm);
		res.fm = gb;
		
		cap[i].fz *=(gb/cap[i].fm);
		cap[i].fm = gb;
		
		res.fz += cap[i].fz;
		sum+=(res.fz/res.fm);
		res.fz %= res.fm;     //先求余 
		gy = gcd(res.fm,res.fz);
		
		res.fz /= gy;
		res.fm /= gy; 
	}
	if(sum!=0) 
	{
	printf("%lld",sum);
	if(res.fz != 0) printf(" ");
	}
	if(res.fz!=0) printf("%lld/%lld\n",res.fz,res.fm);
	else if(res.fz==0&&sum==0) printf("0\n");
	return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值