数据结构(二十一)
学习数据结构与算法过程中的心得体会以及知识点的整理,方便我自己查找,也希望可以和大家一起交流。
—— N个数求和 ——
1.题目描述
本题的要求很简单,就是求N个数字的和。麻烦的是,这些数字是以有理数分子/分母的形式给出的,你输出的和也必须是有理数的形式。
1.1输入格式:
输入第一行给出一个正整数N(≤100)。随后一行按格式
a1/b1 a2/b2...
给出N个有理数。题目保证所有分子和分母都在长整型范围内。另外,负数的符号一定出现在分子前面。
1.2输出格式:
输出上述数字和的最简形式 —— 即将结果写成整数部分分数部分,其中分数部分写成分子/分母,要求分子小于分母,且它们没有公因子。如果结果的整数部分为0,则只输出分数部分。
1.3样例输入与输出
输入样例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
2.代码实现
c
#include<stdio.h>
#include<stdlib.h>
long sum_int,sum_son,sum_mom;
long gongyinshu(long mom1,long mom2)
{
long m1=mom1,m2=mom2,ys;
while(m2!=0)
{
ys=m1%m2;
m1=m2;
m2=ys;
}
return m1;
}
int main()
{
int a;
long c,d;
scanf("%d",&a);
long num[a][2];
for(int i=0;i<a;i++)
{
scanf("%ld/%ld",&c,&d);
if(d==0)
{
i--;
break;
}
num[i][0]=c;
num[i][1]=d;
}
long gbs,gys;//公倍数、公因数
sum_int=0;
sum_son=num[0][0];
sum_mom=num[0][1];
for(int i=1;i<a;i++)
{
if(num[i][1]==sum_mom)
sum_son=sum_son+num[i][0];
else
{
gys=gongyinshu(num[i][1],sum_mom);
gbs=num[i][1]*sum_mom/gys;
num[i][0]=num[i][0]*(gbs/num[i][1]);
sum_son=sum_son*(gbs/sum_mom)+num[i][0];
sum_mom=gbs;
}
}
if(sum_son>sum_mom)
{
sum_int=sum_son/sum_mom;
sum_son=sum_son%sum_mom;
}
if(sum_int==0 && sum_son==0)
printf("0");
if(sum_int!=0)
printf("%ld",sum_int);
if(sum_son!=0)
{
gys=gongyinshu(sum_mom,sum_son);
sum_son=sum_son/gys;
sum_mom=sum_mom/gys;
if(sum_int!=0)
printf(" %ld/%ld",sum_son,sum_mom);
else
printf("%ld/%ld",sum_son,sum_mom);
}
return 0;
}
3.代码说明
本段代码基本可以通过测试点,如果有测试点报错“答案错误”或者“浮点错误”,应该是由于该测试点的测试数据中分数的分子分母位数过大,直接利用相乘到公倍数再相加的整个运算超过了long的大小,解决方法就是把后面的化简的部分(循环)直接并入到输入的循环中去。这样可以一边输入一边公倍数相加运算一边化简相加后的分数,这样可以确保整个计算过程不超过long的大小。