题目描述:
本题要求编写程序,计算 2 个有理数的和、差、积、商。
输入格式:
输入在一行中按照 a1/b1 a2/b2 的格式给出两个分数形式的有理数,其中分子和分母全是整型范围内的整数,负号只可能出现在分子前,分母不为 0。
输入样例:
输出格式:
分别在 4 行中按照 有理数1 运算符 有理数2 = 结果 的格式顺序输出 2 个有理数的和、差、积、商。注意输出的每个有理数必须是该有理数的最简形式 k a/b,其中 k 是整数部分,a/b 是最简分数部分;若为负数,则须加括号;若除法分母为 0,则输出 Inf。题目保证正确的输出中没有超过整型范围的整数。
输出样例:
这道题花了我很长时间,其实不是题目有多难,主要是要正确地把一个分数按题目要求表示出来。定义一个函数print_num(a,b) , a是分子,b是分母,该函数将a,b表示的分数正确打印出来。那么对于题中要输出的加减乘除四则运算:首先用这个函数将第一个和第二个分数正确打印,然后将这两个分数由运算法则计算得到的结果的分子和分母代入函数中,将结果这个分数正确打印。
一些坑:
- 注意计算后分母为0这种特殊情况(函数中判断后打印Inf)
- 乘积运算结果可能会出int范围,所以开始要用long long定义变量。
- 计算得到的结果要进行化简,然后再做后面的处理。比如8/6,如果不化简,打印结果就是1 2/6 就错了。先化简的话,8/6变成4/3 再处理就得到正确结果1 1/3。
#include<iostream>
#include<algorithm>
using namespace std;
int gcd(long long a, long long b){
if(b == 0)
return a;
else
return gcd(b, a%b);
}
void print_num(long long a, long long b){
if(b == 0){
cout<<"Inf";
return;
}
if(a == 0){
cout<<"0";
return;
}
bool flag = ((a < 0 && b > 0) || (a > 0 && b < 0));
if(flag) cout<<"(-";
a = abs(a);b = abs(b);
long long t = gcd(a,b);
a /= t; b /= t;
long long x = a/b;
if(x != 0){
cout<<x;
if(a%b == 0 && flag){
cout<<")";
return;
}
if(a%b != 0 && flag){
cout<<" "<<a-x*b<<"/"<<b<<")";
return;
}
if(a%b != 0 && flag == 0){
cout<<" "<<a-x*b<<"/"<<b;
return;
}
}else{
cout<<a<<"/"<<b;
if(flag) cout<<")";
}
}
int main(){
long long a1, b1, a2, b2;
scanf("%lld/%lld %lld/%lld",&a1, &b1, &a2, &b2);
//加法
print_num(a1,b1);
cout<<" + ";
print_num(a2,b2);
cout<<" = ";
print_num(a1*b2+a2*b1, b1*b2);
cout<<endl;
//减法
print_num(a1,b1);
cout<<" - ";
print_num(a2,b2);
cout<<" = ";
print_num(a1*b2-a2*b1, b1*b2);
cout<<endl;
//乘法
print_num(a1,b1);
cout<<" * ";
print_num(a2,b2);
cout<<" = ";
print_num(a1*a2, b1*b2);
cout<<endl;
//除法
print_num(a1,b1);
cout<<" / ";
print_num(a2,b2);
cout<<" = ";
print_num(a1*b2, a2*b1);
return 0;
}