河北大学程序设计训练营
[TOC]
2-4 N个数求和 (30分)
本题的要求很简单,就是求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型表示范围,因此保险起见,直接用long long来存储好喽。这种情况尤其体现在分数的乘法除法过程中。
- 约分化简主要利用的是欧几里得算法求最大公约数。
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); }
|
- 格式输出时注意输出格式,符号是跟在分数部分的。之后无非就是整数,真分数,假分数的处理。真假根据
abs(r.up) > r.down
代码句进行区分。
题解代码:
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 56 57 58 59 60 61 62 63 64 65 66 67 68
| #include <iostream> #include <cstdio> #include <math.h> using namespace std; int gcd(int a, int b) { if( b == 0) return a; else return gcd( b, a % b); }
struct Fraction //分数 { int up, down; }; Fraction reduction(Fraction result) { if(result.down < 0) { result.up = - result.up; result.down = - result.down; } if(result.up == 0) { result.down = 1; } else { int d = gcd(abs(result.up), abs(result.down)); if(d) { result.up /= d; result.down /= d; } } return result; }
void showResult(Fraction r) { r = reduction(r); if(r.down == 1) cout << r.up; else if(abs(r.up) > r.down) { cout << abs(r.up) / abs(r.down) << " " << abs(r.up) % r.down << "/" << r.down; } else { cout << r.up << "/" << r.down; } } int main() { int n; cin >> n; long long fz = 0, fm = 1, z, m; while(n--) { scanf("%d/%d", &z, &m); fz = fz * m + z * fm; fm = fm * m; } Fraction result; result.up = fz; result.down = fm; Fraction r = reduction(result); showResult(r); return 0; }
|
关于分数处理知识点的补充
分数的表示
1 2 3 4
| struct Fraction //分数 { int up, down; };
|
分数的化简
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
| Fraction reduction(Fraction result) { if(result.down < 0) { result.up = - result.up; result.down = - result.down; } if(result.up == 0) { result.down = 1; } else { int d = gcd(abs(result.up), abs(result.down)); if(d) { result.up /= d; result.down /= d; } } return result; }
|
分数的输出
1 2 3 4 5 6 7 8 9 10 11 12 13
| void showResult(Fraction r) { r = reduction(r); if(r.down == 1) cout << r.up; else if(abs(r.up) > r.down) { cout << abs(r.up) / abs(r.down) << " " << abs(r.up) % r.down << "/" << r.down; } else { cout << r.up << "/" << r.down; } }
|
这些格式化的东西,多熟练一下,下次拿过来就可以用。