洛谷 题解 P1572 计算分数
输入格式
输入一行,为一个分数计算式。
计算式中只包含数字、+、-、/。其中 / 为分数线,分数线左边为分子,右边为分母。输入数据保证不会出现繁分数。如果输入计算式的第一项为正,不会有前缀 + 号;若为负,会有前缀 - 号。
所有整数均以分数形式出现。
输出格式
输出一行,为最后的计算结果(用最简分数或整数表示)。
保证答案内出现的所有数(如果答案是分数即为分子和分母)均在 64 位带符号整数的表示范围之内。
样例
样例输入 #1
2/1+1/3-1/4
样例输出 #1
25/12
样例输入 #2
1/2+1/3+1/4-1/4+1/5-1/5+6/1-6/1
样例输出 #2
5/6
样例输入 #3
7/4+1/3+8/5-3/2-6/9-6/4-5/2+6/2+4/9-3/9-2/3+5/2-5/4+3/9-3/8-5/8+6/8+3/8-4/7-5/7-3/6+6/9-5/6-5/7-5/2
样例输出 #3
-1259/360
样例输入 #4
1/2-1/2
样例输出 #4
0
提示
对于所有测试点,输入计算式长度在 100 以内,分子、分母在 1000 以内。
题解
思路
1.数据读取
2.通分累加
3.约分输出
C代码
#include <stdio.h>
/*辗转相除法计算最大公约数*/
int greatest_common_divisor(int i, int j) {
int a = i, b = j;
if (a < b) {
int temp = a;
a = b;
b = temp;
}
int m = a * b;
int c = a % b;
while (c) {
a = b;
b = c;
c = a % b;
}
return b;
}
/*通分*/
void add(int* a, int* b) {
int LCM = a[1] * b[1] / greatest_common_divisor(a[1], b[1]);
/*LCM为最大公约数(least_common_multiple)*/
a[0] = a[0] * LCM / a[1] + b[0] * LCM / b[1];
a[1] = LCM;
}
int main() {
int num[2];//num[0]存储当前正读入分数的分子,num[1]存储当前正读入分数的分母
int ans[2];//ans[0]存储当前已累加分数的分子,ans[1]存储当前已累加分数的分母
scanf("%d/%d", &ans[0], &ans[1]);//先读入第一个分数
while (scanf("%d/%d", &num[0], &num[1]) != EOF) {
add(ans, (int*)(num));
}
/*分子为0时直接输出,避免约分时计算最大公倍数因为除数为0而报错*/
if(ans[0] == 0){
printf("0");
return 0;
}
/*将最后结果约分*/
int GCD = greatest_common_divisor(ans[0], ans[1]);
ans[0] /= GCD;
ans[1] /= GCD;
/*不知道为啥偶尔ans[]分子位置的负号会出现在分母位置,所以只好手动调换两者符号了*/
if (ans[1] < 0) {
ans[0] *= -1;
ans[1] *= -1;
}
if (ans[1] != 1)
printf("%d/%d\n", ans[0], ans[1]);
else
printf("%d", ans[0]);
return 0;
}
通过详情


浙公网安备 33010602011771号