题目
本题要求编写程序,计算 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
思路
gcd函数
欧几里得算法,也就是高中数学书上的辗转相除法。他的核心是:gcd(a,b) == gcd(b,a % b) ,而终止递归的条件就是b(除数)变为了0,这个时候已经返回了a,b的最大公约数。
//gcd算法
int gcd(int a,int b) {
if(b == 0)
return a;
return gcd(b,a % b);
}
还有个简版:
long long gcd(long long a,long long b) {return b == 0 ? a : gcd(b,a % b);}
注意点
- 负数要有括号,为了判断是否为负数,用一个flag保存是否为负数,是de话就要输入括号与负号。
- 假分数时的整数部分若为0不输出,但分子分母能整除时只输出整数部分
- 分母为0时输出Inf,分子为0时输出0.记住一旦为0要return 直接跳出,不进行接下来的操作。(看了好久
- 输入的记住用long long,数据有点大(a1*b1时可能爆掉)
- 注意空格
代码:
gcd函数寻找最大公约数,workout函数进行格式化输出。
//foreverking
#include <vector>
#include <cstdio>
#include <queue>
#include <algorithm>
#include <cstring>
#include <iostream>
#include <cmath>
using namespace std;
//分子和分母全是整型范围内的整数,负号只可能出现在分子前,分母不为 0
long long a1,a2,b1,b2;
//gcd,辗转相除求最大公约数
long long gcd(long long a,long long b) {
//return b == 0 ? a : gcd(b,a % b);
if(b == 0)
return a;
return gcd(b,a % b);
}
//输出处理过后的数字
void workOut(long long m,long long n) {
//判断有0没
if(m * n == 0) {
if(m == 0) cout << 0;
if(n == 0) cout << "Inf";
return;
}
//这是一个负数,注意负号要在分子,而且负号有括号
bool flag = 0;
if((m < 0 && n > 0) || (m > 0 && n < 0))
flag = 1;;//是负数则flag为1
m = abs(m);
n = abs(n);//都取绝对值
long long num = m / n;//如果是带分数,那么这是整数部分
long long x = gcd(m,n);//最大公约数
m /= x;
n /= x;//得出约分后的分子分母
m = m - num * n;
if(flag == 1) cout << "(-";//实际负数,输出括号与负号
if(num != 0) cout << num;//有整数部分,输出
//可以整除,没有分数部分了,是负数就输出括号,不是直接返回了
if(m % n== 0){
if(flag == 1) cout << ')';
return;
}
if(num != 0) cout << ' ';
cout << m << '/' << n;
if(flag == 1) cout << ')';
}
int main() {
//a1/b1 a2/b2
scanf("%lld/%lld %lld/%lld",&a1,&b1,&a2,&b2);
//加法
workOut(a1,b1);
cout << " + ";
workOut(a2,b2);
cout << " = ";
workOut(a1 * b2 + a2 * b1, b1 * b2);
cout << endl;
//减法
workOut(a1, b1);
cout << " - ";
workOut(a2, b2);
cout << " = ";
workOut(a1 * b2 - a2 * b1,b1 * b2);
cout << endl;
//乘法
workOut(a1, b1);
cout << " * ";
workOut(a2, b2);
cout << " = ";
workOut(a1 * a2,b1 * b2);
cout << endl;
//除法
workOut(a1,b1);
cout << " / ";
workOut(a2,b2);
cout << " = ";
workOut(a1 * b2,b1 * a2);
cout << endl;
return 0;
}
有一些语句是可以优化的。 题目链接