PAT乙级 1034 有理数四则运算 (20分)
程序员文章站
2022-06-13 15:42:40
...
1034 有理数四则运算 (20分)
本题要求编写程序,计算 2 个有理数的和、差、积、商。
输入格式:
输入在一行中按照 a1/b1 a2/b2 的格式给出两个分数形式的有理数,其中分子和分母全是整型范围内的整数,负号只可能出现在分子前,分母不为 0。
输出格式:
分别在 4 行中按照 有理数1 运算符 有理数2 = 结果 的格式顺序输出 2 个有理数的和、差、积、商。注意输出的每个有理数必须是该有理数的最简形式 k a/b,其中 k 是整数部分,a/b 是最简分数部分;若为负数,则须加括号;若除法分母为 0,则输出 Inf。题目保证正确的输出中没有超过整型范围的整数。
输入样例 1:
2/3 -4/2
输出样例 1:
2/3 + (-2) = (-1 1/3)
2/3 - (-2) = 2 2/3
2/3 * (-2) = (-1 1/3)
2/3 / (-2) = (-1/3)
输入样例 2:
5/3 0/6
输出样例 2:
1 2/3 + 0 = 1 2/3
1 2/3 - 0 = 1 2/3
1 2/3 * 0 = 0
1 2/3 / 0 = Inf
思路:
一看就是个超级麻烦的题啊。
而且不仅麻烦,还有很多坑在里面,比如分母不能为0,运算过程中涉及两个整型相乘可能会溢出等等。
主要问题就是比较麻烦,还有最坑的坑点在于整型溢出,其他的都还好,关键步骤我在代码中用注释说明白了。
统计数据:
题解 方法一:
看起来很乱是不是~
#include <cstdio>
using namespace std;
long long a,b,c,d,e,f,g,comm_bei,tmpa;
long long gcd(long long a,long long b){ //最大公约数的标准代码,建议背过
return !b?a:gcd(b,a%b);
}
void prt(long long a,long long b){ //这是一个集大成的函数,包含了很多功能
if(b==0) { //在除法中,如果分母为0,则输出Inf
printf("Inf");
return;
}
if((a>0 && b<0) || (a<0 && b<0)) { //保证a和b中,负号只有可能出现在a的身上。
a=-a;
b=-b;
}
long long tmpa = a,tmp_gcd; //用tmpa记录a的正负号,因为接下来a要取绝对值
!a ? printf("0") : 1; //0要单独处理
a<0 ? printf("(-"),a=-a : 1; //如果是负数,输出 (-
tmp_gcd = gcd(a,b); //取最大公约数
a = a / tmp_gcd;
b = b / tmp_gcd;
a/b ? printf("%lld",a/b) : 1; //如果是真分数,输出a/b
((a/b) && (a%b)) ? printf(" ") : 1; //如果是真分数而且不是整数,输出一个空格
a%b ? printf("%lld/%lld",a%b,b) : 1; //如果不是整数,输出"a/b"
tmpa<0 ? printf(")") : 1; //如果是负数,要把后面的括号补上 )
}
int main(){
scanf("%lld/%lld %lld/%lld",&a,&b,&c,&d);
prt(a,b);printf(" + ");prt(c,d);printf(" = ");prt(a*d + b*c,b*d);printf("\n");
prt(a,b);printf(" - ");prt(c,d);printf(" = ");prt(a*d - b*c,b*d);printf("\n");
prt(a,b);printf(" * ");prt(c,d);printf(" = ");prt(a*c,b*d);printf("\n");
prt(a,b);printf(" / ");prt(c,d);printf(" = ");prt(a*d,b*c);
return 0;
}