题目
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
思路
模拟两个分数加法:
a1/b1 + a2/b2
取公分母为b1、b2的最小公倍数,即 b1 * b2 / g (g是b1、b2的最大公约数,如12、8的最小公倍数为12 * 8 / 4 = 24);
则分子为a1 * b2 / g + a2 * b1 / g。
(为了防止中间结果越界可以先除后乘)
取第一个分数a1/b1为初始值,逐个与后面n-1个分数相加,结果一直保存在a1、b1中。
将最终结果化简为整数部分和小数部分,按要求输出即可。
求最大公约数时手动实现了辗转相除法,其实algorithm.h
中有库函数:__gcd(a, b)
可以直接调用。
代码
#include <iostream>
using namespace std;
long gcd(long a, long b){
while (b!=0){
long r = a % b;
a = b;
b = r;
}
return a;
}
int main(){
int n;
long a1, b1;
scanf("%d %ld/%ld", &n, &a1, &b1);
for (int i=1; i<n; i++){
long a2, b2;
scanf("%ld/%ld", &a2, &b2);
long g = gcd(b1, b2); //最大公约数
a1 = b2 / g * a1 + b1 / g * a2;
b1 = b1 / g * b2;
}
if (a1 < 0){
a1 = -a1;
printf("-");
}
if (a1 == 0){
printf("0");
}
long i = a1 / b1; //取整数部分
a1 %= b1; //去掉整数后的小数部分
if (i != 0){
printf("%ld", i);
}
if (a1 != 0){
if (i != 0){
printf(" ");
}
long g = gcd(a1, b1);
printf("%ld/%ld", a1/g, b1/g);
}
return 0;
}