L1-009 N个数求和 (测试点3和测试点5

分享一道平时写的题
本题的要求很简单,就是求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

测试点3是测试的长整型,关键点:看函数返回类型是否也是长整型
测试点5的测试是所有分子加起来后刚好等于0,直接输出0就行

#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
#include<stdlib.h>
long long gcd(long long a, long long b)//辗转相除法
{
    while (b)
    {
        long long tmp = a % b;
        a = b;
        b = tmp;
    }
    return a;


}

int main()
{
    int n = 0;
    scanf("%d", &n);
    long long* arr1 = (long long*)calloc(n, sizeof(long long));//存分子
    long long* arr2 = (long long*)calloc(n, sizeof(long long));//存分母
    int i = 0;
    long long tmp = 0;//原本准备创建一个临时变量,后来当成分母用了
    for (i = 0; i < n; i++)
    {
        scanf("%lld/%lld", arr1 + i, arr2 + i);
        if(arr1[i]==0)
        {
            n--;
            i--;
            continue;
        }
        if (!i)//当i=0时,不需要算最小公倍数
        {
            tmp = arr2[0];
        }
        else
        {
            long long gcd1 = gcd(arr2[i], tmp);
            tmp = (arr2[i] * tmp) / gcd1;//这里算 所有分母的最小公倍数=两数相乘/最大公约数
        }
    }
   
   
    long long sum = 0;//sum是分子
    while (n > 0)
    {
        sum += tmp / arr2[n - 1] * arr1[n - 1];//所有分子通分后加起来
        n--;
    }
    if(sum==0)//如果分子为零(测试点5)
    {
        printf("0");
        return 0;
    }
    long long gc = gcd(sum%tmp, tmp);
    
    
    if (sum / tmp==0)
    {
            printf("%lld/%lld\n", sum/ gc, tmp / gc);
    }
    else if (sum%tmp==0)
    {
        printf("%lld\n", sum / tmp);
    }
    else
    {
        printf("%lld %lld/%lld\n", sum / tmp, sum % tmp / gc, tmp / gc);
    }
    free(arr1);
    free(arr2);
    arr1=NULL;
    arr2=NULL;

    return 0;
}
  • 4
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值