PAT(Basic Level) Practice : 1034 有理数四则运算 (20分)
1034 有理数四则运算 (20分)
测试点2:结果错误
“分子和分母全是整形范围内的整数”,但是两个整数相乘会超出整数int的范围。
在未化简之前,乘法过程中,分子分母相乘可能会超出范围。
使用long long ,而不是long(和int一样是4个字节)
用法:"%lld"
测试点3:运行超时
运行超时,最坑的地方...
cout转printf,不行。
后来查了一下,要使用辗转相除法求最大公约数,然后来约分才不会超时。
long long gcd(long longa,long long b)
{
return b==0?a:gcd(b,a%b);
}
gcd返回值有可能是0,要判断一下,不要除以0导致浮点错误
代码
#include <iostream>
#include"stdlib.h"
#include <vector>
#include <string>
#include <cstdio>
//scanf printf防止超时
#include <algorithm>
//vector的sort
#include <sstream>
//转换
using namespace std;
#include<iomanip>
//精度
#include<cmath>
//round四舍五入取整
class number
{
public:
bool isMinus;
long long num1;//分子
long long num2;//分母
long long integ;//整数部分
number()
{
isMinus=false;
num1=0;num2=0;integ=0;
}
};
//辗转相除法求最大公约数
long long gcd(long long a,long long b)
{
return b==0?a:gcd(b,a%b);
}
//消除公因子
void simplify(number & num)
{
long long temp=gcd(num.num1,num.num2);
if(temp!=0)
{
num.num1/=temp;
num.num2/=temp;
}
}
//取整数
void simplify1(number & num)
{
if(num.num1==0)
{
num.num2==0;
}else{
num.integ=num.num1/num.num2;
num.num1=num.num1%num.num2;
}
}
number add(const number & n1,const number & n2)
{
if(n1.num1==0)
return n2;
if(n2.num1==0)
return n1;
number res;
long long t1,t2;
if(n1.isMinus)
{
t1=(-1)*n1.num1*n2.num2;
}else{
t1=n1.num1*n2.num2;
}
if(n2.isMinus)
{
t2=(-1)*n2.num1*n1.num2;
}else{
t2=n2.num1*n1.num2;
}
t1+=t2;
if(t1<0)
{
res.isMinus=true;
res.num1=abs(t1);
}else{
res.isMinus=false;
res.num1=t1;
}
res.num2=n1.num2*n2.num2;
return res;
}
number multiply(const number & n1,const number & n2)
{
number res;
if(n1.num1==0||n2.num1==0)
{
res.isMinus=false;
res.num1=0;
res.num2=0;
return res;
}
if((n1.isMinus&&(!n2.isMinus))||(n2.isMinus&&(!n1.isMinus)))
{
res.isMinus=true;
}else{
res.isMinus=false;
}
res.num1=n1.num1*n2.num1;
res.num2=n1.num2*n2.num2;
return res;
}
void output(number n)
{
if(n.integ==0&&n.num1==0)
{
printf("0");
}else if(n.isMinus){
//cout<<"(-";
printf("(-");
if(n.integ==0)
{
//cout<<n.num1<<"/"<<n.num2;
printf("%lld/%lld",n.num1,n.num2);
}else if(n.num1==0)
{
//cout<<n.integ;
printf("%lld",n.integ);
}else{
//cout<<n.integ<<" "<<n.num1<<"/"<<n.num2;
printf("%lld %lld/%lld",n.integ,n.num1,n.num2);
}
//cout<<")";
printf(")");
}else{
if(n.integ==0)
{
//cout<<n.num1<<"/"<<n.num2;
printf("%lld/%lld",n.num1,n.num2);
}else if(n.num1==0)
{
//cout<<n.integ;
printf("%lld",n.integ);
}else{
//cout<<n.integ<<" "<<n.num1<<"/"<<n.num2;
printf("%lld %lld/%lld",n.integ,n.num1,n.num2);
}
}
}
int main()
{
long long a1,b1,a2,b2;
scanf("%lld/%lld %lld/%lld",&a1,&b1,&a2,&b2);
number n1,n2;
n1.isMinus=a1<0;
n1.num1=abs(a1);
n1.num2=b1;
n2.isMinus=a2<0;
n2.num1=abs(a2);
n2.num2=b2;
simplify(n1);
simplify(n2);
//+
number res1;
res1=add(n1,n2);
simplify(res1);
number n1_out=n1;
number n2_out=n2;
simplify1(n1_out);
simplify1(n2_out);
simplify1(res1);
output(n1_out);
//cout<<" + ";
printf(" + ");
output(n2_out);
//cout<<" = ";
printf(" = ");
output(res1);
//cout<<endl;
printf("\n");
//-
number n3;
if(n2.isMinus)
{
n3.isMinus=false;
}else{
n3.isMinus=true;
}
n3.num1=n2.num1;
n3.num2=n2.num2;
number res2;
res2=add(n1,n3);
simplify(res2);
simplify1(res2);
output(n1_out);
//cout<<" - ";
printf(" - ");
output(n2_out);
//cout<<" = ";
printf(" = ");
output(res2);
//cout<<endl;
printf("\n");
//*
number res3;
res3=multiply(n1,n2);
simplify(res3);
simplify1(res3);
output(n1_out);
//cout<<" * ";
printf(" * ");
output(n2_out);
//cout<<" = ";
printf(" = ");
output(res3);
//cout<<endl;
printf("\n");
//division
output(n1_out);
//cout<<" / ";
printf(" / ");
output(n2_out);
//cout<<" = ";
printf(" = ");
if(n2.num1==0)
{
//cout<<"Inf"<<endl;
printf("Inf\n");
}
else{
int temp=n2.num1;
n2.num1=n2.num2;
n2.num2=temp;
number res4=multiply(n1,n2);
simplify(res4);
simplify1(res4);
output(res4);
//cout<<endl;
printf("\n");
}
return 0;
}