本题要求编写程序,计算N个有理数的平均值。
输入格式:
输入第一行给出正整数N(≤100);第二行中按照a1/b1 a2/b2 …的格式给出N个分数形式的有理数,其中分子和分母全是整形范围内的整数;如果是负数,则负号一定出现在最前面。
输出格式:
在一行中按照a/b的格式输出N个有理数的平均值。注意必须是该有理数的最简分数形式,若分母为1,则只输出分子。
输入样例1:
4
1/2 1/6 3/6 -5/10
输出样例1:
1/6
输入样例2:
2
4/3 2/3
输出样例2:
输入格式:
输入第一行给出正整数N(≤100);第二行中按照a1/b1 a2/b2 …的格式给出N个分数形式的有理数,其中分子和分母全是整形范围内的整数;如果是负数,则负号一定出现在最前面。
输出格式:
在一行中按照a/b的格式输出N个有理数的平均值。注意必须是该有理数的最简分数形式,若分母为1,则只输出分子。
输入样例1:
4
1/2 1/6 3/6 -5/10
输出样例1:
1/6
输入样例2:
2
4/3 2/3
输出样例2:
1
本题细节:
1.分子和分母全是整形范围内的整数,说明有负数和0的情况出现,0的情况要单独处理,负数则可以正常处理
2.平均值,说明相加完有理数后需要除以有理数个数,即分母乘以有理数个数
3.最简分数形式,说明得到分式后还需要将分子分母同除以它们的最大公约数
4.若分母为1,则只输出分子,这个情况可以单独判定
解法1:
1.思路:
先将所有有理数的分母相乘得到各个分母的最大公倍数,再将这个最大公倍数除以各个分母再乘以对应的分子,得到所有有理数通分后的结果,再将分子相加,得到和,最后分子分母同除以它们的最大公约数即可。
2.注意点:
此解法得到的数值可能会超过int类型的范围,故用long long类型可以通过
3.代码:
#include<iostream> using namespace std; typedef long long ll; ll GCD(ll a,ll b)//求最大公约数 { if(a<b) { ll t=a; a=b; b=t; } ll c=a%b; if(c==0) return b; while(c) { a=b; b=c; c=a%b; } return b; } int main() { int N; cin>>N; ll *a=new ll[N]; ll *b=new ll[N]; ll prd_deno=1,sum_numr=0;//定义分母的乘积,分子的和 char c; for(int i=0;i<N;i++) cin>>a[i]>>c>>b[i]; if(N==1&&a[0]==0)//如果输入一个且分子为0 { cout<<0; return 0; } for(int i=0;i<N;i++)//求分母的最大公倍数 prd_deno*=b[i]; for(int i=0;i<N;i++)//改变分子 a[i]*=(prd_deno/b[i]); for(int i=0;i<N;i++)//分子相加 sum_numr+=a[i]; if(sum_numr==0)//如果分子的和为0 { cout<<0; return 0; } prd_deno*=N;//求均值,分母乘以有理数个数 ll gcd_numr=sum_numr/GCD(sum_numr,prd_deno);//求约分后的分子 ll gcd_deno=prd_deno/GCD(sum_numr,prd_deno);//求约分后的分母 if(gcd_deno==1) cout<<gcd_numr; else cout<<gcd_numr<<'/'<<gcd_deno; return 0; }
解法2(推荐):
1.思路:
此解法类似于动态规划(dynamic programming)的策略,逐个将当前两项分式通分,通分的时候分子分母各自迭代上去,最终得到所有有理数通分后的分式,再通过最大公约数约分,此算法的好处在于,效率比较高,而且即使是使用int类型也能通过,代码也比前一个解法简洁。
2.代码:
#include<iostream> using namespace std; int main() { int N; cin>>N; int *a=new int[N]; int *b=new int[N]; char c; for(int i=0;i<N;i++) cin>>a[i]>>c>>b[i]; int numr=a[0],deno=b[0];//初始化分子,分母 for(int i=1;i<N;i++) { numr=numr*b[i]+deno*a[i]; deno*=b[i];//通分,迭代 } deno*=N;//求均值,分母乘以个数 if(numr==0) { cout<<0; return 0; } int A=numr,B=deno,r;//保留分子,分母,定义余数 while(B) { r=A%B; A=B; B=r; }//求两数的最大公约数 cout<<numr/A; if(deno/A!=1) cout<<'/'<<deno/A; }