问题描述
思路分析
问题分解
-
输入处理:将分数拆解为分子和分母,存储并处理。
-
分数相加规则:
即分子相加、分母相乘。
-
结果化简:求分数的最大公因数(GCD),将其约分至最简形式。
-
带分数处理:
-
分数可以表示为:
-
如果分子整除分母,则结果为整数;否则需要输出带分数形式。
-
具体思路
-
读取输入
- 输入第一行为分数个数
N
,第二行为N
个分数,格式为分子/分母
。
- 输入第一行为分数个数
-
初始化和变量定义
- 定义两个变量,分别表示结果分子和分母,初始值为
0/1
。
- 定义两个变量,分别表示结果分子和分母,初始值为
-
分数求和
- 对每个输入的分数,按加法规则更新:
- 新的分子为:
sum_numerator = sum_numerator × 当前分母 + 当前分子 × sum_denominator
; - 新的分母为:
sum_denominator = sum_denominator × 当前分母
。
- 新的分子为:
- 在每次相加后,调用 约分函数,保持分数为最简形式。
- 对每个输入的分数,按加法规则更新:
-
结果格式化
- 分解为整数部分和分数部分:
- 整数部分:
整数 = 分子 ÷ 分母
; - 分数部分:
新分子 = 分子 % 分母
。
- 整数部分:
- 输出规则:
- 如果整数部分为
0
,只输出分数部分; - 如果分数部分为
0
,只输出整数部分; - 否则输出“整数部分 + 分数部分”。
- 如果整数部分为
- 分解为整数部分和分数部分:
参考代码(C)
#include <stdio.h>// 计算最大公因数(GCD)
long long gcd(long long a, long long b) {return b == 0 ? a : gcd(b, a % b);
}// 约分函数
void simplify(long long *numerator, long long *denominator) {long long g = gcd(*numerator, *denominator);*numerator /= g;*denominator /= g;
}// 主函数
int main() {int N;scanf("%d", &N);long long sum_numerator = 0, sum_denominator = 1;for (int i = 0; i < N; i++) {long long numerator, denominator;scanf("%lld/%lld", &numerator, &denominator);// 分数相加sum_numerator = sum_numerator * denominator + numerator * sum_denominator;sum_denominator *= denominator;// 约分中间结果simplify(&sum_numerator, &sum_denominator);}// 处理结果为整数和分数部分long long integer_part = sum_numerator / sum_denominator;long long fraction_numerator = sum_numerator % sum_denominator;if (fraction_numerator == 0) {printf("%lld\n", integer_part); // 只有整数部分} else {if (integer_part != 0) {printf("%lld %lld/%lld\n", integer_part, fraction_numerator, sum_denominator);} else {printf("%lld/%lld\n", fraction_numerator, sum_denominator);}}return 0;
}
代码分析
1. gcd函数
long long gcd(long long a, long long b) {return b == 0 ? a : gcd(b, a % b);
}
- 功能:计算两个整数
a
和b
的最大公因数(GCD)。 - 逻辑:
- 如果
b = 0
,则 GCD 是a
; - 否则递归调用:
gcd(a, b) = gcd(b, a % b)
。
- 如果
- 作用:用于约分分数。
2. simplify函数
void simplify(long long *numerator, long long *denominator) {long long g = gcd(*numerator, *denominator);*numerator /= g;*denominator /= g;
}
- 功能:将分数化为最简形式。
- 逻辑:
- 使用
gcd
计算分子和分母的最大公因数g
; - 用
g
将分子和分母同时除以g
,达到约分效果。
- 使用
- 作用:保持所有分数在每次加法后都为最简形式,避免数字膨胀。
3. 主函数结构
int main() {int N;scanf("%d", &N);long long sum_numerator = 0, sum_denominator = 1;for (int i = 0; i < N; i++) {long long numerator, denominator;scanf("%lld/%lld", &numerator, &denominator);// 分数相加sum_numerator = sum_numerator * denominator + numerator * sum_denominator;sum_denominator *= denominator;// 约分中间结果simplify(&sum_numerator, &sum_denominator);}
- 功能:主函数实现分数求和与结果输出。
- 逻辑:
- 输入处理:
- 读取整数
N
和N
个分数; - 将每个分数拆解为分子和分母。
- 读取整数
- 分数相加:
-
使用公式:
-
更新总分数的分子和分母。
-
- 中间约分:
- 每次相加后调用
simplify
,将结果化为最简形式,防止分子和分母增长过快。
- 每次相加后调用
- 输入处理:
4. 结果格式化与输出
long long integer_part = sum_numerator / sum_denominator;long long fraction_numerator = sum_numerator % sum_denominator;if (fraction_numerator == 0) {printf("%lld\n", integer_part); // 只有整数部分} else {if (integer_part != 0) {printf("%lld %lld/%lld\n", integer_part, fraction_numerator, sum_denominator);} else {printf("%lld/%lld\n", fraction_numerator, sum_denominator);}}
- 功能:将总和分为整数部分和分数部分,并按要求格式化输出。
- 逻辑:
- 整数部分:计算
integer_part = 分子 ÷ 分母
; - 分数部分:计算
fraction_numerator = 分子 % 分母
; - 输出规则:
- 如果没有分数部分(即分子能整除分母),直接输出整数;
- 如果没有整数部分(整数部分为 0),仅输出分数;
- 否则输出“整数部分 + 分数部分”。
- 整数部分:计算