题意:给定两个有理数,然后计算有理数的加减乘除的结果,但是要满足题目所给定的格式。
思路:把+-*/=这几个符号单独拿出来打印,用一个函数对参加运算的数和结果进行化简打印。首先判断是否有0的存在,如果有,看是否是分母,分母则打印Inf,否则打印0返回,接着判断是否为异号,异号不要直接相乘判断符号,否则会发生溢出,如果是符号就要做打印括号的准备,将所有的数置为正数然后计算,因为前面已经将符号判断出来了,所以直接使用绝对值计算即可。计算其系数,然后打印系数,在判断是否m能够整除n,能够整除则说明这个式子能够化简成整数,根据符号是否打印括号。如果不是则需要进行化简,最后打印结果。
代码:
#include<iostream>
typedef long long int LL;
using namespace std;
LL gcd(LL a, LL b) {//求最大公约数
return b == 0 ? a : gcd(b, a%b);
}
void fun(LL m,LL n) {
if (m == 0 || n == 0) {//先判断是否有没有0
printf("%s", n == 0 ? "Inf" : "0");//分母是否为0
return;
}
bool flag = ((m < 0 && n>0) || (m > 0 && n < 0));//判断是否为异号
if (flag)printf("(-");//如果是负数就要打印双括号
m = abs(m), n = abs(n);
LL x = m / n;
if (x != 0)printf("%lld",x);//打印系数
if (m%n == 0) {
if (flag)printf(")");//如果能够整除代表系数就是化简后的值
return;
}
if (x != 0)printf(" ");//打印系数后的空格
m = m - x * n;//化成假分数之后分子要减去前面的系数
LL t = gcd(m, n);
m = m / t; n = n/t;
printf("%lld/%lld%s", m, n, flag ? ")" : "");//打印分子分母
}
int main() {
LL a = 0, b = 0, c = 0, d = 0;
scanf("%lld/%lld %lld/%lld", &a, &b, &c, &d);
fun(a, b); printf(" + "); fun(c, d); printf(" = "); fun(a*d + c * b, b*d); printf("\n");
fun(a, b); printf(" - "); fun(c, d); printf(" = "); fun(a*d - c * b, b*d); printf("\n");
fun(a, b); printf(" * "); fun(c, d); printf(" = "); fun(a*c, b*d); printf("\n");
fun(a, b); printf(" / "); fun(c, d); printf(" = "); fun(a*d, b*c); printf("\n");
system("pause");
return 0;
}