题目如下:
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/3Sample Output 1:
3 1/3Sample Input 2:
2 4/3 2/3Sample Output 2:
2Sample Input 3:
3 1/3 -1/6 1/8Sample Output 3:
7/24
题目要求对分数进行处理,题目的关键在于求取最大公约数,最初我采用了循环出现超时,后来改用辗转相除法,解决了此问题。需要注意的是分子为负数的情况,为方便处理,我们把负数取绝对值,并且记录下符号,最后再输出。
辗转相除法如下:
给定数a、b,要求他们的最大公约数,用任意一个除以另一个,得到余数c,如果c=0,则说明除尽,除数就是最大公约数;如果c≠0,则用除数再去除以余数,如此循环下去,直至c=0,则除数就是最大公约数,直接说比较抽象,下面用例子说明。
设a=25,b=10,c为余数
①25/10,c=5≠0,令a=10,b=5。
②10/5,c=0,则b=5就是最大公约数。
求取最大公约数的代码如下:
long getMaxCommon(long a, long b){ long yu; if(a == b) return a; while(1){ yu = a % b; if(yu == 0) return b; a = b; b = yu; } }
完整代码如下:
#include <iostream> #include <stdio.h> #include <vector> using namespace std; struct Ration{ long num; long den; Ration(long _n, long _d){ num = _n; den = _d; } }; long getMaxCommon(long a, long b){ long yu; if(a == b) return a; while(1){ yu = a % b; if(yu == 0) return b; a = b; b = yu; } } int main(){ int N; long num,den; long maxDen = -1; cin >> N; vector<Ration> rations; for(int i = 0; i < N; i++){ scanf("%ld/%ld",&num,&den); rations.push_back(Ration(num,den)); if(maxDen == -1){ maxDen = den; }else{ // 找maxDen和当前的最小公倍数 if(den == maxDen) continue; else if(maxDen > den){ if(maxDen % den == 0) continue; }else{ if(den % maxDen == 0){ maxDen = den; continue; } } maxDen = maxDen * den; } } num = 0; for(int i = 0; i < N; i++){ num += rations[i].num * (maxDen / rations[i].den); } if(num == 0) { printf("0\n"); return 0; } bool negative = num < 0; if(negative) num = -num; if(num >= maxDen){ long integer = num / maxDen; long numerator = num % maxDen; if(numerator == 0){ if(negative) printf("-%ld\n",integer); else printf("%ld\n",integer); return 0; } long common = getMaxCommon(numerator,maxDen); if(negative){ printf("%ld -%ld/%ld\n",integer,numerator/common,maxDen / common); }else{ printf("%ld %ld/%ld\n",integer,numerator/common,maxDen / common); } }else{ long common = getMaxCommon(num,maxDen); if(negative) printf("-%ld/%ld\n",num/common,maxDen/common); else printf("%ld/%ld\n",num/common,maxDen/common); } return 0; }