P1572. 计算分数

考点

  • 最大公约数

题解

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;

ll gcd(ll a, ll b) { return b ? gcd(b, a % b) : a; }

ll lcm(ll a, ll b) { return 1ll * a * b / gcd(a, b); }

int main() {
bool flag = 0;
ll ra = 0, rb = 1, a, b, tmp;
while (~scanf("%lld/%lld", &a, &b)) {
tmp = lcm(rb, b);
ra = ra * tmp / rb + a * tmp / b, rb = tmp;
if (ra < 0) flag = 1, ra = -ra;
tmp = gcd(ra, rb);
ra /= tmp, rb /= tmp;
if (flag) flag = 0, ra = -ra;
}
printf("%lld", ra);
if (rb != 1) printf("/%lld", rb);
return 0;
}

思路

正常模拟通分和约分的过程即可,有两个注意点:

  1. 辗转相除法(欧几里得算法)不能处理负数

    所以若分子为负数,先转为正数处理,结果再加上负号

  2. 如果分母为1,只需要输出分子