L1-009 N个数求和 (20 分)
*试题链接:https://pintia.cn/problem-sets/994805046380707840/problems/994805133597065216
GCD最大公约数
正整数a和b的最大公约数是指a和b的所有公约数中最大的那个公约数,即a和b能一起除以的最大的一个因数。
求解最大公约数常用欧几里得算法(即辗转相除法)
设a和b均为正整数,则gcd(a, b)=gcd(b,a%b)
递归式:gcd(a, b)=gcd(b,a%b)
递归边界:gcd(a, 0)=a
代码
int gcd(int a, int b){
if(b==0){
return a;
}else{
return gcd(b, a%b);
}
}
简化代码
int gcd(int a, int b){
return !b?a:(gcd(b, a%b));
}
最小公倍数
最小公倍数即正整数a和b所有公倍数中最小的那个公倍数,一般是在最大公约数的基础上在进行计算的。当计算得最大公约数为d,那么a和b的最小公倍数为a/d * b,这种计算方法要比a*b/d要好,因为先除再乘不会造成结果溢出导致计算错误。
题目:
本题的要求很简单,就是求N个数字的和。麻烦的是,这些数字是以有理数分子/分母的形式给出的,你输出的和也必须是有理数的形式。
输入格式:
输入第一行给出一个正整数N(≤100)。随后一行按格式a1/b1 a2/b2 …给出N个有理数。题目保证所有分子和分母都在长整型范围内。另外,负数的符号一定出现在分子前面。
输出格式:
输出上述数字和的最简形式 —— 即将结果写成整数部分 分数部分,其中分数部分写成分子/分母,要求分子小于分母,且它们没有公因子。如果结果的整数部分为0,则只输出分数部分。
输入样例:
5
2/5 4/15 1/30 -2/60 8/3
输出样例:
3 1/3
大致思路:
本题大致就是基础的先分母通分然后分子也乘上分母通分过程中的因数然后分子相加得到结果,其中需要注意的是在分母通分过程中以及分子分母约分过程中使用的GCD最大公约数以及最小公倍数的部分。
具体代码如下:
#include <iostream>
#include <bits/stdc++.h>
using namespace std;
int gcd(int a, int b){
if(b==0){
return a;
}else{
return gcd(b, a%b);
}
}
int main()
{
int n, fz=0, fm=1, fzz=0, fmm=1;
cin>>n;
for(int i=0;i<n;i++){
if(i==0){
scanf("%d/%d", &fz, &fm);
}
else{
scanf("%d/%d", &fzz, &fmm);
int maxy = gcd(fm, fmm);
fz = (fz * fmm)/ maxy ;
fzz = (fzz * fm) / maxy ;
fz = fz + fzz;
fm = fm / maxy * fmm;
maxy = gcd(fz, fm);
fz = fz/maxy;
fm = fm/maxy;
}
//cout<<fz<<"/"<<fm<<endl;
}
if(fz%fm==0){
cout<<fz/fm<<endl;
}else{
if(fz>fm){
cout<<fz/fm<<" ";
}
fz = fz%fm;
printf("%d/%d", fz, fm);
}
return 0;
}
马上天梯赛,基础不能错!需要不断的练习!!加油!!继续冲鸭!