天梯赛 L1-009 N个数求和 (20分) 附最小公倍数和最大公约数求法

L1-009 N个数求和 (20分)

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

最小公倍数和最大公约数求法

//最小公倍数=两整数的乘积÷最大公约数

//辗转相除法
/*
1. a % b 得余数 c
2. if c == 0, 则 b 为最大公约数
3. if c != 0, 则 a = b, b = c 继续执行 1.
*/
#include <iostream>
#include <stdio.h>

using namespace std;

int main()
{
    int m, n, a, b, c;
    printf("Input two integer numbers:\n");
    scanf("%d%d", &a, &b);
    m = a;
    n = b;
    while(b != 0){
        c = a % b;
        a = b;
        b = c;
    }
    printf("%d\n", a);      //最大公约数
    printf("%d\n", m*n/a);   //最小公倍数
    return 0;
}

//简写
int gcd(int a, int b){
    if(b == 0)
        return a;
    return gcd(b, a % b);
}

//枚举法
int gcd = 1;
for(int k = 2; k <= a && k <= b; k++){
    if(a % k == 0 && b % k == 0)
        gcd = k;
}

//加减法
/*
1. 若a>b,则a=a-b
2. 若a < b,则b=b-a
3. 若a=b,则a(或b)即为两数的最大公约数
4. 若a≠b,则再回去执行1
*/
#include<stdio.h>

int main ( )  /* 相减法求最大公约数 */
{
   int m, n, a, b, c;
   printf("Input two integer numbers:\n");
   scanf ("%d,%d", &a, &b);
   m=a;
   n=b;
   while ( a!=b)
       if (a>b)
           a=a-b;
       else
           b=b-a;
    printf("%d\n", a);     //最大公约数
    printf("%d\n", m*n/a);    //最小公倍数
}

答案1

#include <iostream>
#include <stdio.h>

using namespace std;

long long gcd(long long x, long long y){
    if(x == 0)
        return 0;
    else return (y == 0)? x : gcd(y, x%y);
}

int main()
{
    int n;
    scanf("%d", &n);
    long long a, b, c, d;
    scanf("%lld/%lld", &a, &b);
    int t = gcd(a, b);
    if(t){
        //先给输入的分数约分一下
        a /= t;
        b /= t;
    }
    int i = 1;    //已经输入了一个分数了,故i从1开始
    while(i < n){
        scanf("%lld/%lld", &c, &d);
        long long lcp = b * d/gcd(b, d);   //分母的最小公倍数
        a = a * lcp / b + c * lcp / d;
        b = lcp;
        t = gcd(a, b);    //一边加一边约分
        if(t){
            a /= t;
            b /= t;
        }
        i++;
    }
    if(a && a / b == 0)    //真分数
        printf("%lld/%lld\n", a%b, b);
    else if(!(a % b))    //整数
        printf("%lld\n", a/b);
    else
        printf("%lld %lld/%lld\n", a / b, a % b, b);
    return 0;
}

答案2

结构体的方法

#include <iostream>
#include <algorithm>

using namespace std;

struct node{
    long long fz;
    long long fm;

}frac[110];

int main(){
    int n;
    cin >> n;
    char c;   //存输入的“/”号
    int sum = 1;
    int s = 0;   //总的分子的和
    for(int i = 0; i < n; i++){
        cin >> frac[i].fz >> c >> frac[i].fm;
        sum *= frac[i].fm;      //公共分母, 不知道会不会出现特别大的分母,看看能不能通过,再说
    }
    for(int i = 0; i < n; i++){
        int num  = frac[i].fz;
        for(int j = 0; j < n; j++){
            if(i != j)   //用分子去乘其他所有的分母
                num *= frac[j].fm;
        }
        s += num;
    }
    if(s == 0)                //0
        cout << "0" << endl;
    else if(s % sum == 0)     //整数
        cout << s/sum << endl;
    else{
        if(s / sum >= 1){     //假分数
            int a = s / sum;
            s %= sum;
            int gcd = __gcd(s, sum);
            cout << a << " " << s / gcd << "/" << sum / gcd << endl;
            //这里用scanf好了,cout有点麻烦,同除gcd约分
        }
        else{
            int gcd = __gcd(s, sum);
            cout << s / gcd << "/" << sum / gcd << endl;
        }
    }
    return 0;
}

用了内置的__gcd()函数 #algorithm

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值