题目链接
思路很简单,先求所有分母的最小公倍数,即通分后分子相加,common就是最小公倍数,也是通分后的分母,获取整数部分resint=resa/common,获取分数部分的分子resa=resa%common,分母就是common,还需要进行约分,首先需要求分子分母的最大公约数,要注意分子为0时不能用gcd求最大公约数,因为用gcd辗转相除用到较小数当分母,而分母不能为0.
开始写的代码在pta练习集提交满分,但是在牛客网上对于下面的样例我的程序错误输出了1/-3,发现求-1和3的最大公约数时,因为3%-1=0,会返回的最大公约数是-1,这样-1/3就变成了1/-3,既然约分时用到的最大公约数对正负号无影响,所以传递参数时可以都传正数,就过了所有样例了。
输入: 2 -2/3 1/3
正确输出:-1/3
还有要注意的是long long的变量scanf读入时需要格式为%lld
有时间再学习一下带负数的取模运算机制,待补充······
·
·
·
·
·
完整代码:
#include <iostream>
#include <cstdio>
typedef long long ll;
using namespace std;
ll gcd(ll a,ll b);
int main() {
ll a[101],b[101];
ll N;
cin >> N;
ll common;//储存分母的最小公倍数
for(ll i=1;i<=N;i++){
scanf("%lld/%lld",&a[i],&b[i]);//lld
}
common=b[1];
for(ll i=2;i<=N;i++){
ll g=gcd(common,b[i]);
common=common*b[i]/g;
}
ll resint=0,resa=0,resb=0;
for(ll i=1;i<=N;i++){
resa+=common/b[i]*a[i];
}
resint=resa/common;
resa=resa%common;
if(resa!=0){//分子不为0才有约分的必要
ll tmpa=gcd(max(resa,-resa),common);
resa/=tmpa;
resb=common/tmpa;
}
if(resint==0 && resa!=0) {
printf("%d/%d",resa,resb);
}
else if(resa==0) cout << resint;
else{
cout << resint << " ";
printf("%d/%d",resa,resb);
}
return 0;
}
ll gcd(ll a,ll b){
ll big=max(a,b);
ll small=min(a,b);
ll yu=big%small;
while(yu!=0){
big=small;
small=yu;
yu=big%small;
}
return small;
}