原文链接:我的个人博客
原题链接:1088 Rational Arithmetic
考点
分数化简、最大公因数
思路
这个题目难度不是很大,主要是比较繁琐。主要的任务就是对分数化为真分式,在化简的过程中涉及到求最大公因数。另外值得注意的是,题目中已经说明了数据都是长整型的。因此这里都需要用long long来接收。在判断分数正负时,不要直接使用m*n
,这样会溢出,要注意
代码
#include <bits/stdc++.h>
using namespace std;
long a,b,c,d,m,n;
//辗转相除法(欧几里得算法)
long gcd(long a, long b)
{
if(a<b) swap(a,b);//a始终是大的数
if(a % b == 0)
return b;
else
return gcd(b, a%b);//(a,b)和(b,a mod b)的公约数是一样的,其最大公约数也必然相等
}
// 两个整数的最小公倍数等于两整数之积除以最大公约数
long lcm(long a, long b)
{
return a*b / gcd(a, b);
}
void func(long long m,long long n){//m/n
//对n/m进行化简
if(m*n==0){//分子分母有一个为0
printf("%s",n==0?"Inf":"0");
return;
}
bool flag = (m>0&&n<0)||(m<0&&n>0);//有负数
if(flag) cout<<"(-";
m = abs(m);
n = abs(n);
long long x = m/n;
if(x!=0) cout<<x;
if(m%n==0){
if(flag) cout<<")";
return;
}
if(x!=0) cout<<" ";
m -= x*n;//更新分母
long long t = gcd(m,n);
m/=t;
n/=t;
cout<<m<<'/'<<n;
if(flag) cout<<")";
}
int main(){
scanf("%lld/%lld %lld/%lld",&a,&b,&c,&d);
func(a, b); printf(" + "); func(c, d); printf(" = "); func(a * d + b * c, b * d); printf("\n");
func(a, b); printf(" - "); func(c, d); printf(" = "); func(a * d - b * c, b * d); printf("\n");
func(a, b); printf(" * "); func(c, d); printf(" = "); func(a * c, b * d); printf("\n");
func(a, b); printf(" / "); func(c, d); printf(" = "); func(a * d, b * c);
}