7-5 N个数求和
本题的要求很简单,就是求N个数字的和。麻烦的是,这些数字是以有理数分子/分母的形式给出的,你输出的和也必须是有理数的形式。
输入格式:
输入第一行给出一个正整数N(≤100)。随后一行按格式a1/b1 a2/b2 …给出N个有理数。题目保证所有分子和分母都在长整型范围内。另外,负数的符号一定出现在分子前面。
输出格式:
输出上述数字和的最简形式 —— 即将结果写成整数部分 分数部分,其中分数部分写成分子/分母,要求分子小于分母,且它们没有公因子。如果结果的整数部分为0,则只输出分数部分。
输入样例1:
5
2/5 4/15 1/30 -2/60 8/3
输出样例1:
3 1/3
输入样例2:
2
4/3 2/3
输出样例2:
2
输入样例3:
3
1/3 -1/6 1/8
输出样例3:
7/24
思路:
- 分数用结构体存储
- 每输入一个分数,累加,约分
- 按输出格式输出(分为纯整数、真分数、假分数和零)
注意点
相加过程中可能使分子或分母超过int型表示范围,有两种处理方法:
1.直接用long long来存储。这种情况尤其体现在分数的乘法除法过程中;
2.每次相加后就约分,避免分子分母过大。
约分化简主要利用的是欧几里得算法求最大公约数。
1 2 3 4 5
| int gcd(int a, int b) { if( b == 0) return a; else return gcd( b, a % b); }
|
更简洁的写法:
1 2 3 4
| int Gcd(int a, int b) { return !b ? a : Gcd(b, a % b); }
|
分数累加时,要通分,注意先改变分子,再改变分母(因为分子需要利用原来的分母构成)
题解代码:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55
| #include<iostream> using namespace std;
struct Fraction{ int fz; int fm; };
int Gcd(int a,int b){ if(b==0) return a; return Gcd(b,a%b); }
Fraction yue(Fraction f){
int y=Gcd(abs(f.fz),abs(f.fm)); f.fz/=y; f.fm/=y; return f; }
int main(){ int n; cin >> n; Fraction res; res.fm=1; res.fz=0; while(n--){ int a,b; scanf("%d/%d",&a,&b); res.fz=res.fz*b+res.fm*a; res.fm*=b; res=yue(res); } int zheng=0; if(abs(res.fz) >= abs(res.fm)){ zheng=res.fz/res.fm; cout<<zheng; res.fz=res.fz%res.fm; if(res.fz!=0){ cout<<" "<<res.fz<<"/"<<res.fm; } }else{ if(res.fz==0) cout<<"0"; else{ cout<<res.fz<<"/"<<res.fm; } } return 0; }
|