题目来源
注意点:
- 只输出整数,只输出小数以及正常输出都要加换行
- 注意特判输出0
题目大意
给出若干有理数,求和,按照最简分数的格式输出
思路简介
逐个按照分数加法相加即可
- 先通分:求分母最大公约数,然后计算最大公倍数
- 分子相加
- 求分子分母公约数化简
注意几个细节:
- 计算时,整数类型应为
long long否则会爆整数,python版自带高精度不用考虑这个问题 - 只输出整数,只输出小数以及正常输出都要加换行
- 注意特判输出 0 0 0, 0 0 0 也要带换行
python 当中的 fraction.Fraction(a,b) 正好是这种类型
Fraction(a,b) 类型即以 a 为分子,b 为分母的分数,其中 a,b 都是整数,可以去掉通分的过程
本题当中有个不是很严谨的地方,举个例子
-2/3的最简分数应当是-1 1/3,但是不论是-2/3还是前者,答案都是对的,没有设置这类的样例
c++代码中为了简便(其实是博主偷懒没写 )使用的是-2/3而
python代码当中由于是用库计算的,会更加的标准,答案则是-1 1/3
遇到的问题
- 只输出整数时忘记换行
- 类型开错
代码
c++ 版
cpp
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
ll gcd(ll a,ll b){
return (!b?a:gcd(b,a%b));
}
void solve(){
int n;cin>>n;
vector<ll>a(n),b(n);
for(int i=0;i<n;++i){
char c;
cin>>a[i]>>c>>b[i];
}
ll resa=a[0],resb=b[0];
for(int i=1;i<n;++i){
ll g=gcd(resb,b[i]);
ll c=resb/g*b[i];
a[i]*=resb/g;
resa*=b[i]/g;
resa+=a[i];
resb=c;
g=gcd(resa,resb);
resa/=g,resb/=g;
}
if(!resa){
cout<<0<<'\n';
return;
}
int g=gcd(resa,resb);
resa/=g,resb/=g;
ll k=resa/resb;
resa=resa-k*resb;
if(k&&resa)cout<<k<<' '<<resa<<'/'<<resb;
else if(k)cout<<k;
else cout<<resa<<'/'<<resb;
cout<<'\n';
}
int main(){
ios::sync_with_stdio(0);cin.tie(0);cout.tie(0);
//fstream in("in.txt");cin.rdbuf(in.rdbuf());
int t=1;
//cin>>t;
while(t--){
solve();
}
return 0;
}
python 版
python
from fractions import Fraction
def solve(data):
n=int(data[0])
ans=Fraction(0,1) # 构造Fraction类型
for i in range(1,n+1):
a,b=map(int,data[i].split('/'))
ans+=Fraction(a,b)
if ans==0:
print(0)
return
n=ans.numerator
d=ans.denominator
inter=n//d
numer=n%d
if inter and numer:
print(f"{inter} {numer}/{d}")
elif inter:
print(inter)
else:
print(f"{numer}/{d}")
import sys
def main():
sys.stdin = open("in.txt")
data=sys.stdin.read().split()
solve(data)
if __name__ == "__main__":
main()