本题要求编写程序,计算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
参考代码:
#include<stdio.h>
#include<stdlib.h>
void Simplify(int *a,int *b);//分数化简
int main()
{
/*sumA,sumB分别为累加和的分子和分母,
avgA,avgB分别为平均值的分子和分母*/
int i,N,a,b,sumA,sumB,avgA,avgB;
scanf("%d",&N);
scanf("%d/%d",&a,&b);
Simplify(&a,&b);//化简a/b
sumA=a;
sumB=b;
for(i=1;i<N;i++)//累加求和
{
scanf("%d/%d",&a,&b);
Simplify(&a,&b);//化简每一次输入的有理数(如果输入不化简有一个测试点不通过)
sumA=sumA*b+a*sumB; //求累加和的分子
sumB*=b; //求累加和的分母
Simplify(&sumA,&sumB);//化简累加和
}
if(sumA==0) printf("0\n");//如果累加和的分子为零,直接输出0
else //否则求平均值
{
avgA=sumA;
avgB=sumB*N;
Simplify(&avgA,&avgB);//化简平均值
if(avgB==1) //如果分母为1,只输出分子
{
printf("%d\n",avgA);
}
else
{
printf("%d/%d\n",avgA,avgB);
}
}
return 0;
}
void Simplify(int *a,int *b)
{
if(*a!=0) //如果分子不为零
{
int t;
t=abs(*a)>*b?*b:abs(*a);//找分子分母中最小的值
for(int i=t;i>=1;i--)//从最小值往下遍历,找最大公约数
{
if(*a%i==0&&*b%i==0)//如果i是最大公约数
{
*a/=i;
*b/=i;
break;
}
}
}
else //如果分子为零
{
*a=0; //将分子赋为0
*b=1; //将分母赋为1
}
}
思路:
这题思路不是很难,具体步骤参考代码及注释即可。但有些需要注意的点:输入的数可能分子为零;不仅每次求和的结果需要化简,每次输入的分数也需要化简,否则会溢出出错。