PTA7-35 有理数均值(20 分)双解法

本题要求编写程序,计算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:

1

本题细节:

1.分子和分母全是整形范围内的整数,说明有负数和0的情况出现,0的情况要单独处理,负数则可以正常处理

2.平均值,说明相加完有理数后需要除以有理数个数,即分母乘以有理数个数

3.最简分数形式,说明得到分式后还需要将分子分母同除以它们的最大公约数

4.若分母为1,则只输出分子,这个情况可以单独判定

解法1:

1.思路:

先将所有有理数的分母相乘得到各个分母的最大公倍数,再将这个最大公倍数除以各个分母再乘以对应的分子,得到所有有理数通分后的结果,再将分子相加,得到和,最后分子分母同除以它们的最大公约数即可。

2.注意点:

此解法得到的数值可能会超过int类型的范围,故用long long类型可以通过

扫描二维码关注公众号,回复: 1604172 查看本文章

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;
}

猜你喜欢

转载自blog.csdn.net/qq_37729102/article/details/80691033
今日推荐