逐次通分相加并立即用 gcd 约分,保持最简后按整数或分数格式输出。
OJ: roj
题目 ID: 1209
难度:入门
标签:模拟gcd分数
创建: 2026-09-29 23:39
更新: 2026-10-05 05:37
题目描述
输入 p/q 形式的分数(不含空格,p/q 表示。
样例:输入第一行 2,接下来两行 1/2、1/3,输出 5/6。
思路
用一个分数
参考代码
Python 版:
python
#!/usr/bin/env python3
# Author by Rainboy blog: https://rainboylv.com github: https://github.com/rainboylvx
# rbook: -> https://rbook.roj.ac.cn https://rbook2.roj.ac.cn
# rainboy的学习导航网站: https://idx.roj.ac.cn
# create_at: 2026-09-29 23:39
# update_at: 2026-09-29 23:39
import sys
from math import gcd
from functools import reduce
def add(acc: tuple[int, int], s: str) -> tuple[int, int]:
"""把当前累加和 acc=a/b 与分数 s=p/q 相加,返回最简形式。"""
a, b = acc
p, q = map(int, s.split('/'))
x, y = a * q + b * p, b * q
g = gcd(x, y)
return x // g, y // g
def solve() -> None:
data = sys.stdin.buffer.read().decode().split()
n = int(data[0])
a, b = reduce(add, data[1:], (0, 1))
print(a if b == 1 else f"{a}/{b}")
if __name__ == "__main__":
solve()C++ 版(同一算法):
cpp
/**
* Author by Rainboy blog: https://rainboylv.com github: https://github.com/rainboylvx
* rbook: -> https://rbook.roj.ac.cn https://rbook2.roj.ac.cn
* rainboy的学习导航网站: https://idx.roj.ac.cn
* create_at: 2026-10-05 05:37
* update_at: 2026-10-05 05:37
*/
#include <cstdio>
#include <algorithm>
typedef long long ll;
// 当前累加和保存为分数 a / b,始终保持最简形式
ll a = 0, b = 1;
// 计算最大公约数,用于约分
ll my_gcd(ll x, ll y) {
if (y == 0) return x;
return my_gcd(y, x % y);
}
int main() {
int n;
scanf("%d", &n);
for (int i = 1; i <= n; i++) {
ll p, q;
scanf("%lld/%lld", &p, &q);
// 通分相加:a/b + p/q = (a*q + b*p) / (b*q)
a = a * q + b * p;
b = b * q;
// 立即约分,保持最简
ll g = my_gcd(a, b);
a /= g;
b /= g;
}
if (b == 1)
printf("%lld\n", a); // 分母为 1 时只输出整数
else
printf("%lld/%lld\n", a, b);
return 0;
}