1. 程式人生 > >L1-009. N個數求和-PAT團體程式設計天梯賽GPLT

L1-009. N個數求和-PAT團體程式設計天梯賽GPLT

L1-009. 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

分析:先根據分數加法的公式累加,後分離出整數部分和分數部分。


分子和分母都在長整型內,所以不能用int儲存,否則有一個測試點不通過。
一開始一直是浮點錯誤,按理來說應該是出現了/0或者%0的情況,找了半天也不知道錯在哪裡。
後來注意到應該在累加的時候考慮是否會超出long long的範圍,所以在累加每一步之前進行分子分母的約分處理,然後就AC了。
以及:abs()在stdlib.h標頭檔案裡面。
應該還要考慮整數和小數部分都為0時候輸出0的情況,但是測試用例中不涉及,所以如果沒有最後兩句也是可以AC的。

#include <cstdio>
#include <cstdlib>
using namespace std;
long long gcd(long long a, long long b) {return b == 0 ? a : gcd(b, a % b);}
int main() {
    long long n, a, b, suma = 0, sumb = 1, gcdvalue;
    scanf("%lld", &n);
    for(int i = 0; i < n; i++) {
        scanf("%lld/%lld", &a, &b);
        gcdvalue = (suma == 0 || sumb == 0) ? 1 : gcd(abs(suma), abs(sumb));
        sumb = sumb / gcdvalue;
        suma = suma / gcdvalue;
        gcdvalue = (a == 0 || b == 0) ? 1 : gcd(abs(a), abs(b));
        a = a / gcdvalue;
        b = b / gcdvalue;
        suma = a * sumb + suma * b;
        sumb = b * sumb;
    }
    long long integer = suma / sumb;
    suma = suma - (sumb * integer);
    gcdvalue = (suma == 0 || sumb == 0) ? 1 : gcd(abs(suma), abs(sumb));
    suma = suma / gcdvalue;
    sumb = sumb / gcdvalue;
    if(integer != 0) {
        printf("%lld", integer);
        if(suma != 0)
            printf(" ");
    }
    if(suma != 0) {
        printf("%lld/%lld", suma, sumb);
    }
    if(integer == 0 && suma == 0)
        printf("0");
    return 0;
}