/*
题意:
1、给出一个数,然后几个分数,有负分数
2、计算分数的和
要求,输出最简单形式,有符号需要加符号
还有,分子分母都是long long
解题:
1、分数变量
2、化简函数
3、加法函数
4、输出函数
learn && wrong:
1、加法,一个符号错,导致全部错
2、负数无需特殊处理,只需把分子当做负数即可,reduction即可
3、数据范围int,两个分母相乘时,最大可以到达long long
4、必须在每一步加法之后进行约分,全部加完约分铁定超时
5、特别注意这一点,最大公约数,计算分子和分母绝对值的公约数
*/
#include <iostream>
#include <algorithm>
using namespace std;
//分数定义以及结构体数组
struct fraction {
long long up;
long long down;
}fac[110];
long long gcd(long long a, long long b) {
if (b == 0) return a;
else return gcd(b, a % b);
}
//分数化简
fraction reduction(fraction result) {
if (result.down < 0) { //分母如果小于0,则令分子为0,
result.up = -result.up;
result.down = -result.down;
}
if (result.up == 0) { //!!!是这样吗 ,对的,负数与0或者非0没有关系
result.down = 1;
}
else {
long long d = gcd(abs(result.up), abs(result.down)); //!!记得是绝对值公约数
result.up = result.up / d;
result.down = result.down / d;
}
return result;
}
//分数加法
fraction add(fraction f1, fraction f2) {
fraction result;
result.up = f1.up * f2.down + f1.down * f2.up;
result.down = f1.down * f2.down;
return reduction(result);
}
//分数输出,整假真
void show_fac(fraction result) {
result = reduction(result); //先化简才能输出
if (result.down == 1) {
printf("%lld", result.up);
}
else if (abs(result.up) > result.down) {
printf("%lld %lld/%lld", result.up / result.down, abs(result.up) % result.down, result.down);
}
else {
printf("%lld/%lld", result.up, result.down);
}
}
int main(int argc, char** argv) {
int num;
cin >> num;
for (int i = 0;i < num;++i) { //输入所有的分数
scanf("%lld/%lld", &fac[i].up, &fac[i].down);
}
struct fraction temp;
temp.up = 0, temp.down = 1;
for (int i = 0;i < num;++i) {//!!! 应该是up为0了
temp = add(temp, fac[i]);
}
show_fac(temp);
return 0;
}