PAT:1081. Rational Sum (20) AC(类似math.h中的sqrt(1.0*n),algorithm的abs()用于取绝对值)
#include<stdio.h>
#include<algorithm>
using namespace std;
typedef long long ll; //【skill】重命名
struct num
{
ll zi,mu; //分子分母
};
ll gcd(ll a,ll b) //求最大公约数
{
return b==0 ? a:gcd(b,a%b);
}
num yuefen(num a) //分数约分
{
//printf("%lld/%lld。约分为:",a.zi,a.mu);
if(a.mu<0) //分母保持正号,统一用分子表示符号
{
a.mu=-a.mu;
a.zi=-a.zi;
}
if(a.zi==0) //分子为0,分数为0,但是加法需要分母相乘合并,将分母设为1方便操作
{
a.mu=1;
}
else
{
int d=gcd(abs(a.zi),abs(a.mu)); //【warning】计算最大公约数的时候要化为正数,abs绝对值
a.mu/=d; //得到最大公约数约分
a.zi/=d;
}
//printf("%lld/%lld\n",a.zi,a.mu);
return a;
}
num ADD(num a,num b)
{
//printf("%lld/%lld + %lld/%lld=",a.zi,a.mu,b.zi,b.mu);
num x;
x.mu=a.mu*b.mu;
x.zi=a.zi*b.mu+a.mu*b.zi;
//printf("%lld/%lld ",x.zi,x.mu);
return yuefen(x); //返回约分后的结果
}
void OUT(num a)
{
yuefen(a);
if(abs(a.zi)>a.mu) //带分数【caution】分子在量上面大于分母abs(a.zi)>a.mu,注意绝对值
{
int dai=a.zi/a.mu;
a.zi=abs(a.zi)%a.mu; //【caution】正负号已经由前面的整数带去了,这里分子要用绝对值保证正数
if(a.zi==0) //【warning】约分后为整数,没有分数部分,如6/3=2
printf("%d",dai);
else
printf("%d %lld/%lld",dai,a.zi,a.mu);
}
else if(a.mu==1) //整数
printf("%lld",a.zi);
else
{
printf("%lld/%lld",a.zi,a.mu); //真分数
}
}
int main()
{
int n;
scanf("%d",&n);
num ans;
ans.mu=1;
ans.zi=0;
for(int i=0 ; i<n ; ++i)
{
num tmp;
scanf("%lld/%lld",&tmp.zi,&tmp.mu);
ans=ADD(ans,tmp);
}
OUT(ans);
return 0;
}