PTA L1-009 N个数求和(详解)

前言:本期是关于pta题目n个数求和的详解介绍,内容包括四个大模块:题目 代码实现 大致思路 代码解读,今天你c了吗?

题目: 

 

本题的要求很简单,就是求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>
int com_div(long long x,long long y)
{
    int tmp = 0;
    while(tmp=x%y)
    {
        x=y;
        y=tmp;
    }
    return y;
}
int main()
{
    int n = 0;
    scanf("%d",&n);
    int i = 0;
    long long a = 0;
    long long b = 0;
    long long suma = 0;
    long long sumb = 0;
    for(i=0;i<n;i++)
    {
        scanf("%lld/%lld",&a,&b);
        if(suma==0)
        {
            suma=a;
            sumb=b;
        }
        else
        {
            suma=suma*b+a*sumb;
            sumb=sumb*b;
        }
        int max=com_div(suma,sumb);
        suma/=max;
        sumb/=max;
    }
    if(suma && (suma/sumb==0))
    {
        printf("%lld/%lld",suma,sumb);
    }
    else if(suma%sumb==0)
    {
        printf("%lld",suma/sumb);
    }
    else
    {
        printf("%lld %lld/%lld",suma/sumb,suma%sumb,sumb);
    }
    return 0;
}

大致思路: 

预备了解:

suma:分数的分子和    sumb:分数的分母和

a:分数的分子               b:分数的分母

com_div函数:求出两数的最大公约数       max:存储最大公约数

1. 每输入一次分数,就与之相加,相加通分后的分子,分母化至最简

2. 若输入的是第一个分数:特殊处理

    此时代表分子和的suma==0,suma赋值成第一个分数的分子,sumb赋值成第一个分数的分母

    若输入的不是第一个分数:

    suma存储两个分数通分后的分子和

    sumb存储两个分数通分后的分母和

3. 打印:三种形式:只有整数部分   只有分数部分    整数部分+分数部分

     只有整数部分: 所有分数相加通分化简后的分子和suma 是分母和sumb的整数倍(即整除)

     只有分数部分:  所有分数相加通分化简后的分子和suma比分母和sumb小,且不能为0

                                 0/任意数=0

                                  suma有可能在通分相加过程中变成0,因为存在负数

    整数部分+分数部分: 所有分数相加通分化简后的分子和suma比分母和sumb大

                                     (不是sumb的倍数)

                                        整数部分:suma/sumb

                                        分数部分:分子:suma%sumb    分母:sumb

          eg.  10/3  对应:整数部分:3   分数部分:1/3

                                     整数部分求法:10/3=3

                                     分数部分求法:分子:10%3=1

                                                               分母:3

代码解读: 

 part 1   求出所有分数相加通分后的分子和,分母和

        scanf("%lld/%lld",&a,&b);
        if(suma==0)
        {
            suma=a;
            sumb=b;
        }
        else
        {
            suma=suma*b+a*sumb;
            sumb=sumb*b;
        }

for循环内部读取每一个分数的分子a,分母b

若是读取的是第一个分数,需要特殊处理(因为第一个分数无需与其他分数相加通分)

suma赋值成第一个分数的分子a

sumb赋值成仪狄格分数的分母b

若读取的不是第一个分数:(此分数需要与别的分数进行相加通分)

下面是简单的通分代码:

            suma=suma*b+a*sumb;
            sumb=sumb*b;

part 2 求出最大公约数,每两个分数相加通分后需化简

        int max=com_div(suma,sumb);
        suma/=max;
        sumb/=max;

com_div是求最大公约数的函数

每次两个分数相加通分后所得的新分子(即两个分数的分子和)suma,新分母(即两个分数的分母和)sumb,需要进行化简,除以最大公约数即可化至最简

以下是求最大公约数的函数:使用的是辗转相除法

int com_div(long long x,long long y)
{
    int tmp = 0;
    while(tmp=x%y)
    {
        x=y;
        y=tmp;
    }
    return y;
}

part 3  打印

    if(suma && (suma/sumb==0))
    {
        printf("%lld/%lld",suma,sumb);
    }
    else if(suma%sumb==0)
    {
        printf("%lld",suma/sumb);
    }
    else
    {
        printf("%lld %lld/%lld",suma/sumb,suma%sumb,sumb);
    }

输出分三种形式:

1. 只有整数部分

    else if(suma%sumb==0)
    {
        printf("%lld",suma/sumb);
    }

2.只有分数部分

    if(suma && (suma/sumb==0))
    {
        printf("%lld/%lld",suma,sumb);
    }

3 整数部分+分数部分

    else
    {
        printf("%lld %lld/%lld",suma/sumb,suma%sumb,sumb);
    }
  • 50
    点赞
  • 132
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值