一、链接
二、题目及代码
本题的要求很简单,就是求N
个数字的和。麻烦的是,这些数字是以有理数分子/分母
的形式给出的,你输出的和也必须是有理数的形式。
输入格式:
输入第一行给出一个正整数N
(≤100)。随后一行按格式a1/b1 a2/b2 ...
给出N
个有理数。题目保证所有分子和分母都在长整型范围内。另外,负数的符号一定出现在分子前面。
输出格式:
输出上述数字和的最简形式 —— 即将结果写成整数部分 分数部分
,其中分数部分写成分子/分母
,要求分子小于分母,且它们没有公因子。如果结果的整数部分为0,则只输出分数部分。
代码:
#include <bits/stdc++.h>
using namespace std;
struct number
{
long long int zi;//分子
char c;//除号
long long int mu;//分母
}s[100]; //定义分数的结构体,收集
int main()
{
int n,i;
long long int zong=1,he=0;
cin >> n;
for (i=0;i<n;i++)
{
scanf("%lld",&s[i].zi);
scanf("%c",&s[i].c);
scanf("%lld",&s[i].mu);
zong *= s[i].mu; //同分母
}
for (i=0;i<n;i++)
he=he+zong/s[i].mu*s[i].zi; //同分母后分子相加
if (he==0)
printf("%lld",he); //若化简前分子为0则直接输出
else if (he<0) //负数情况
{
he*=(-1);
long long int y = __gcd(he,zong);//__gcd()取最大公约数进行化简
he/=y;
zong/=y;
long long int t = he/zong;//取整
long long int l = he%zong;//取余
if (t!=0)
{
if (l!=0)
printf("-%lld -%lld/%lld",t,l,zong);
else
printf("-%lld",t);
}
else
printf("-%lld/%lld",l,zong);
}
else //正数
{
long long int y = __gcd(he,zong);//__gcd()取最大公约数进行化简
he/=y;
zong/=y;
long long int t = he/zong;//取整
long long int l = he%zong;//取余
if (t!=0)
{
if (l!=0)
printf("%lld %lld/%lld",t,l,zong);
else
printf("%lld",t);
}
else
printf("%lld/%lld",l,zong);
}
return 0;
}
三、问题反思
首先理清结构,负分数的分子其实就是一个负整数,int完全可以涵括,不必将其完全拆开思考分数正负的问题。(一开始将负号考虑成了一个字符,纠结半天......)
其次,在后续改代码的时候我想直接把所有整数的情况提出来,就这样:
但运行结果显示我有的情况会出现浮点错误(比如出现除以0的情况),具体我也没查出来......如果有知道的大佬请求指点一下。
最后,最重要的问题——数据类型!!!一开始还会注意数据类型为long long int 型,但到后面忘了,变量定义的都是int型,导致部分数据超出范围直接影响最后结果!改了半天才注意到......