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

该程序接收N个有理数(分子/分母形式),计算它们的和,并以最简有理数形式输出结果。使用辗转相除法找到分母的最小公倍数,然后将所有分子通分相加。如果和为0,则直接输出0;否则,处理分子和分母,确保结果是最简形式。
摘要由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

测试点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;
}
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值