7-1 N个数求和 (20分)
本题的要求很简单,就是求N个数字的和。麻烦的是,这些数字是以有理数分子/分母的形式给出的,你输出的和也必须是有理数的形式。
输入格式:
输入第一行给出一个正整数N(≤100)。随后一行按格式a1/b1 a2/b2 …给出N个有理数。题目保证所有分子和分母都在长整型范围内。另外,负数的符号一定出现在分子前面。
输出格式:
输出上述数字和的最简形式 —— 即将结果写成整数部分 分数部分,其中分数部分写成分子/分母,要求分子小于分母,且它们没有公因子。如果结果的整数部分为0,则只输出分数部分。
输入样例1:
5
2/5 4/15 1/30 -2/60 8/3
输出样例1:
3 1/3
输入样例2:
2
4/3 2/3
输出样例2:
2
输入样例3:
3
1/3 -1/6 1/8
输出样例3:
7/24
感想:好长时间没有敲代码了,这几天一放假就玩疯了,荒废了好长时间,
还好有个小学期警醒着我,你还没学精呢,回过头来做题,真的是啪啪的打脸,完全不知道如何下手了,这题困了我好久,修修改改,一直都是最后一个判断浮点错误,弄得我心神俱疲,因为这事还特意在这上面差看什么意思,是不是我理解有误,果然找到,一直以为只有除以0会报错,实际上对0取余也是会报错的,我就是在这方面的处理上方式不对导致的,之后的方法是用的结构体数组的思路,将分子和分母放到一块来处理,这个思路的来源于自《算法笔记》(说起来好久没看了),之后建立个求公约数的函数,在主函数中利用
f
1.
a
∗
f
2.
b
+
f
2.
a
∗
f
1.
b
f
1.
b
∗
f
2.
b
\frac{f1.a*f2.b+f2.a*f1.b}{f1.b*f2.b}
f1.b∗f2.bf1.a∗f2.b+f2.a∗f1.b的公式,之后求和求公约数,化简便是变得相对简单啦。
#include<stdio.h>
typedef struct node{
long long a; //分子
long long b; //分母
}node;
long long gong(node f){ //求公约数
long long t,x,y;
if(f.a>f.b){
y=f.a;
x=f.b;
}else{
x=f.a;
y=f.b;
}
if(x==0)return 0;
while((t=y%x)!=0){
y=x;
x=t;
}
return x;
}
int main(){
node f[101];
int n,i;
long long t=1;
scanf("%d",&n);
for(i=0;i<n;i++){
scanf("%lld/%lld",&f[i].a,&f[i].b);
}
for(i=1;i<n;i++){
f[0].a=f[0].a*f[i].b+f[0].b*f[i].a; //这两个式子就是上面的分开写法
f[0].b=f[0].b*f[i].b;
t=gong(f[0]); //想的是防止乘出来的数过大,先简化在重复进行上一步
if(t!=0){
f[0].a/=t;
f[0].b/=t;
}
}
if(f[0].b==0){ //这里是处理的对0取余的浮点错误
printf("0");
return 0;
}
if(f[0].a/f[0].b==0&&f[0].a){
printf("%lld/%lld",f[0].a%f[0].b,f[0].b);
}else if(f[0].a%f[0].b==0){
printf("%lld",f[0].a/f[0].b);
}
else{
printf("%lld %lld/%lld",f[0].a/f[0].b,f[0].a%f[0].b,f[0].b);
}
return 0;
}