目录
一、问题描述
本题的要求很简单,就是求N
个数字的和。麻烦的是,这些数字是以有理数分子/分母
的形式给出的,你输出的和也必须是有理数的形式。
1. 输入格式
输入第一行给出一个正整数N
(≤100)。随后一行按格式a1/b1 a2/b2 ...
给出N
个有理数。题目保证所有分子和分母都在长整型范围内。另外,负数的符号一定出现在分子前面。
2. 输出格式
输出上述数字和的最简形式 —— 即将结果写成整数部分 分数部分
,其中分数部分写成分子/分母
,要求分子小于分母,且它们没有公因子。如果结果的整数部分为0,则只输出分数部分。
3. 输入样例
5
2/5 4/15 1/30 -2/60 8/3
4. 输出样例
3 1/3
5. 限制条件
代码长度限制 16 KB
时间限制 400 ms
内存限制 64 MB
栈限制 8192 KB
二、问题分析
1. 数据结构定义:使用Fraction类面向对象定义分数结构(分子和分母)。
2. 重载运算符:operator+、operator>>、operator<<分别用于分数相加、输入分数、输出分数。
3. 分数化简:使用内置的__gcd()函数寻找分子和分母的最大公约数,然后进行化简,最后按照题目的格式要求进行输出即可。
三、源码解答
#include <bits/stdc++.h>
#define ll long long
using namespace std;
class Fraction {
private:
ll numer; //分子
ll deno; //分母
public:
Fraction() {}
Fraction(ll n, ll d): numer(n), deno(d) {}
Fraction operator+(const Fraction& frac) {
ll n = numer * frac.deno + deno * frac.numer;
ll d = deno * frac.deno;
ll g = __gcd(d, n);
return Fraction(n/g, d / g);
}
friend istream& operator>>(istream& in, Fraction& frac) {
char op;
in >> frac.numer >> op >> frac.deno;
return in;
}
friend ostream& operator<<(ostream& out, Fraction& frac) {
if(frac.numer == 0) cout << 0;
else if(frac.deno == 1) cout << frac.numer;
else {
int intpart = frac.numer / frac.deno;
frac.numer %= frac.deno;
if(intpart) cout << intpart << " ";
if(frac.numer * frac.deno < 0) {
if(frac.numer > 0) {
frac.numer = -frac.numer;
frac.deno = -frac.deno;
}
}
out << frac.numer << "/" << frac.deno;
}
return out;
}
};
int main() {
int n; cin >> n;
Fraction res(0, 1), frac;
while(n--) {
cin >> frac;
res = res + frac;
}
cout << res;
return 0;
}