题目
PAT 甲级 1088 Rational Arithmetic (20分)
思路
分数运算
参看:分数运算
易错
1 题目样例范围若为long int,所以需要使用long long类型处理,用int类型会溢出
2 判断是否真假分数时,分子因为可能有负号,需要取绝对值
3 括号,分子为负数时,需要添加括号
4 分数除法,分母为0的情况,需要特殊处理,否则会运行错误
题解
#include <iostream>
#include <vector>
#include <cstring>
#include <unordered_map>
#include <stack>
#include <queue>
#include <algorithm>
#include <cmath>
using namespace std;
typedef long long LL;
// 分数的表示
struct Fraction {
LL u;
LL d;
Fraction(){
u=0;
d=1;
}
};
// 求公约数
LL gcd(LL a,LL b) {
if(b==0)return a;
else return gcd(b,a%b);
}
// 分数的化简
Fraction reduction(Fraction f) {
if(f.d<0) {
f.d=-f.d;
f.u=-f.u;
}
if(f.u==0)f.d=1;
else {
LL g = gcd(abs(f.u),f.d);
if(g!=1){
f.u/=g;
f.d/=g;
}
}
return f;
}
// 分数打印
void print(Fraction f){
if(f.u<0)printf("(");
if(f.d==1)printf("%lld",f.u);
else if(abs(f.u)>f.d){
printf("%lld %lld/%lld",f.u/f.d,abs(f.u)%f.d,f.d);
}else{
printf("%lld/%lld",f.u,f.d);
}
if(f.u<0)printf(")");
}
// 分数的加法
Fraction add(Fraction a, Fraction b){
Fraction c;
c.u=a.u*b.d+a.d*b.u;
c.d=a.d*b.d;
return reduction(c);
}
// 分数的减法
Fraction sub(Fraction a, Fraction b){
Fraction c;
c.u=a.u*b.d-a.d*b.u;
c.d=a.d*b.d;
return reduction(c);
}
// 分数的乘法
Fraction multi(Fraction a, Fraction b){
Fraction c;
c.u=a.u*b.u;
c.d=a.d*b.d;
return reduction(c);
}
// 分数的除法
Fraction divide(Fraction a, Fraction b){
Fraction c;
c.u=a.u*b.d;
c.d=a.d*b.u;
return reduction(c);
}
int main(int argc,char * argv[]) {
Fraction a,b;
scanf("%lld/%lld %lld/%lld",&a.u,&a.d,&b.u,&b.d);
a=reduction(a);
b=reduction(b);
print(a);
printf(" + ");
print(b);
printf(" = ");
print(add(a,b));
printf("\n");
print(a);
printf(" - ");
print(b);
printf(" = ");
print(sub(a,b));
printf("\n");
print(a);
printf(" * ");
print(b);
printf(" = ");
print(multi(a,b));
printf("\n");
print(a);
printf(" / ");
print(b);
printf(" = ");
if(b.u==0)printf("Inf");
else print(divide(a,b));
printf("\n");
return 0;
}