L1-009 N个数求和 (20 分)【补充测试样例】

这篇博客讨论了一道编程题目的错误代码,该题目要求计算一系列有理数之和,并以最简有理数形式输出。原始代码在简化有理数时存在逻辑漏洞,导致错误结果。博主通过分析指出问题在于`gcd`函数未取绝对值,影响了分数简化。修复后的代码能够正确处理负数和确保分子、分母无公因子。
摘要由CSDN通过智能技术生成

题目概述

本题的要求很简单,就是求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

代码

#include <stdio.h>
#include <stdlib.h> 

struct fraction
{
	long long up;
	long long down;
	fraction(){}
	fraction(long long _up,long long _down)
	{
		up=_up;down=_down;//哪个前,哪个后 
	}
}A[100];

long long gcd(long long a,long long b)
{
	if(b==0)
	    return a;
	else
	    return (gcd(b,a%b));//形式!!! 
}

fraction simplify(fraction x)
{
	
	if (x.down<0)
	{
		x.up*=-1;x.down*=-1;
	}
	else if(x.down==0)
	{
		x.down=0;x.up=1;
	}
	long long temp=gcd(abs(x.up),abs(x.down));//这里别乱加else 
	x.up/=temp;x.down/=temp;
	return x;
}

fraction Add(fraction c,fraction d)
{
	fraction s;
	s.up=(c.up*d.down+d.up*c.down);
	s.down=c.down*d.down;
	return s;
}

int main()
{
	int n=0,i;
	fraction sum=fraction(0,1);
	scanf("%d",&n);
	for (i=0;i<n;i++)
	{
		scanf("%lld/%lld",&A[i].up,&A[i].down);
		sum=Add(sum,A[i]);//别忘了重新等号 
		sum=simplify(sum);//同上 
	}
	//考虑负数情况 
	if (sum.up%sum.down==0||(sum.up==0))
	    printf("%lld",sum.up/sum.down);
    else if (abs(sum.up)<abs(sum.down))
	    printf("%lld/%lld",sum.up,sum.down);
	else
	{
		if (sum.up<0)
		{
			printf("%d -%d/%d",abs(sum.up)/abs(sum.down),abs(sum.up)%sum.down,sum.down);
			//printf("%d",abs(sum.up)/abs(sum.down));
			//printf(" -%d",abs(sum.up)%sum.down);
			//printf(" /%d",sum.down);
		}
		else
		    printf("%lld %lld/%lld",sum.up/sum.down,sum.up%sum.down,sum.down);
	}
	return 0;
}

提交结果

在这里插入图片描述

tips:
该题有漏洞,以下代码

#include <stdio.h>
#include <stdlib.h> 

struct fraction
{
	long long up;
	long long down;
	fraction(){}
	fraction(long long _up,long long _down)
	{
		up=_up;down=_down;//哪个前,哪个后 
	}
}A[100];

long long gcd(long long a,long long b)
{
	if(b==0)
	    return a;
	else
	    return (gcd(b,a%b));//形式!!! 
}

fraction simplify(fraction x)
{
	
	if (x.down<0)
	{
		x.up*=-1;x.down*=-1;
	}
	else if(x.down==0)
	{
		x.down=0;x.up=1;
	}
	long long temp=gcd(x.up,x.down);//这里没有取绝对值,导致temp为-值后,对x分母一定为正产生干扰 
	x.up/=temp;x.down/=temp;
	return x;
}

fraction Add(fraction c,fraction d)
{
	fraction s;
	s.up=(c.up*d.down+d.up*c.down);
	s.down=c.down*d.down;
	return s;
}

int main()
{
	int n=0,i;
	fraction sum=fraction(0,1);
	scanf("%d",&n);
	for (i=0;i<n;i++)
	{
		scanf("%lld/%lld",&A[i].up,&A[i].down);
		sum=Add(sum,A[i]);//别忘了重新等号 
		sum=simplify(sum);//同上 
	}
	//考虑负数情况 
	if (sum.up%sum.down==0||(sum.up==0))
	    printf("%lld",sum.up/sum.down);
    else if (abs(sum.up)<abs(sum.down))
	    printf("%lld/%lld",sum.up,sum.down);
	else
	{
		if (sum.up<0)
		    printf("%lld -%lld/%lld",abs(sum.up)/abs(sum.down),abs(sum.up)%sum.down,sum.down);
		else
		    printf("%lld %lld/%lld",sum.up/sum.down,sum.up%sum.down,sum.down);
	}
	return 0;
}

在自己如下测试样例中,得到结果如下截图所示

1
-4/9

在这里插入图片描述
这显然与题意违背,但提交结果仍然是AC
在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

进击的lab681

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值