L1-009 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
前言: 之前呢也做过一次,提交以后全通过了,可是当我又一次去做的时候提交了一下上次成功的代码,居然只有12分了,好郁闷,之前明明是对的呀,可能是上次的不严谨,人家更新了一下就出错了总算搞定了,所以只好重做了,记录一下。
分析: 把要求和的数分成分子分母(z[101],m[101])存到两个长整型数组里去,再定义一个分子变量(zi),一个分母变量(mu),它们就是最后求和结果,把两个数组中的值依次与那两个变量相加。分三种情况判断:
1.当前分母数组里值>=分母变量,且前者可整除后者
2.当前分母数组里的值<分母变量,且后者可整除前者
若是以上两种情况,只需对其中一方进行放缩即可。
3最后就是俩分母不相等了,对两方都放缩
(注:数组里的分母不用操作,只起一个比骄作用)
求和结果都存到zi,和mu中后,就开始化简了,我的想法是从j=2开始,只要j能同时整除分子分母,那么好,我就让j的价值最大化,while循环到j无法同时整除它们两个,结束条件是j同时小于分子分母。
化简完后分情况输出:
1.分子<分母,只输出分数
2.分子>=分母且能整除,只输出整数
3.分子>分母且不能整除,分整数小数输出
坑点:
要注意求和后分子是负数的情况,记得取绝对值
#include<stdio.h>
#include<math.h>
int main()
{
long long zi,mu,z[101]={0},m[101]={0},i,j,zh,y,n;
scanf("%lld",&n);
for(i=0;i<n;i++)
scanf("%lld/%lld",&z[i],&m[i]); //把要求和的数分成分子分母存到长整型数组里去
zi=z[0],mu=m[0];
for(i=1;i<n;i++)//遍历求和
{
if(m[i]>=mu&&(m[i]%mu==0))
{
zi*=(m[i]/mu);
mu*=(m[i]/mu);
}
else if(mu>m[i]&&(mu%m[i]==0))
z[i]*=(mu/m[i]);
else
{
zi*=m[i];
z[i]*=mu;
mu*=m[i];
}
zi+=z[i];
}
for(j=2;j<=abs(zi)&&j<=mu;j++)//化简分子分母,找出两数的公共因子,一定到取绝对值,应为分子(zi)可能是负的,循环就不成立了
{
while((zi%j==0)&&(mu%j==0))//如果j可以同时整除分子分母的话,那就用j除吧,除到不能整除时为止
{
zi/=j;
mu/=j;
}
}
//下面就是分情况输出结果了
if(zi>mu&&zi%mu!=0)
{
zh=(zi-(zi%mu))/mu;
zi%=mu;
printf("%lld %lld/%lld\n",zh,zi,mu);
}
else if(zi%mu==0)
printf("%lld\n",zi/mu);
else
printf("%lld/%lld\n",zi,mu);
return 0;
}