洛谷 题解 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;
}

通过详情

image

posted @   残影0无痕  阅读(173)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 【自荐】一款简洁、开源的在线白板工具 Drawnix
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
· 园子的第一款AI主题卫衣上架——"HELLO! HOW CAN I ASSIST YOU TODAY
· 无需6万激活码!GitHub神秘组织3小时极速复刻Manus,手把手教你使用OpenManus搭建本
点击右上角即可分享
微信分享提示