分数求和

GitHub跳转原题关系图返回列表

逐次通分相加并立即用 gcd 约分,保持最简后按整数或分数格式输出。

OJ: roj

题目 ID: 1209

难度:入门

标签:模拟gcd分数

创建: 2026-09-29 23:39

更新: 2026-10-05 05:37

题目描述

输入 nn(1⩽n⩽101 \leqslant n \leqslant 10)个分数并对它们求和,用最简形式表示结果:分子分母的最大公约数为 11;若分母为 11 则直接输出整数,如 36\frac{3}{6} 化简为 12\frac{1}{2},31\frac{3}{1} 化简为 33。分子和分母均不为 00、不为负数。输入第一行是整数 nn,接下来 nn 行每行一个 p/q 形式的分数(不含空格,p,qp, q 均不超过 1010);输出一行,即最终结果的最简形式,分数用 p/q 表示。

样例:输入第一行 2,接下来两行 1/2、1/3,输出 5/6。

思路

用一个分数 (a,b)(a, b)(初始 0/10/1)做累加器,每读入 p/qp/q 就按 ab+pq=aq+bpbq\frac{a}{b}+\frac{p}{q}=\frac{aq+bp}{bq} 通分相加,并立即用 gcd⁡\gcd 约分保持最简。全部加完后若分母为 11 只输出整数,否则输出 a/ba/b。

参考代码

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;
}