1. 程式人生 > >PTAL1-009 N個數求和解題報告---GCD & LCM

PTAL1-009 N個數求和解題報告---GCD & LCM

                                  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

坑點:分子分母在長整型範圍

求出最小公倍數,然後求出所有分子和,求整數部分,利用最大公約數求小數最簡後的結果

AC Code: 

#include<cstdio>
#include<iostream>
#include<cstring>
#include<algorithm>
#include<cmath>
#include<cctype>
#include<map>
#include<string>
#define INF 0x3f3f3f3f
using namespace std;
typedef long long ll;
struct Node{
	ll mole;	//分子
	ll deno;	//分母
};
ll gcd(ll x, ll y) {
	return y ? gcd(y, x % y) : x;
}
int main() {
	int n;
	while (scanf("%d", &n) != EOF) {
		Node vv[105];
		ll multmaxl, allmole = 0;
		for (int i = 0; i < n; i++) {
			scanf("%lld/%lld", &vv[i].mole, &vv[i].deno);
			if (i == 0) multmaxl = vv[i].deno;
			else {
				multmaxl = multmaxl / gcd(multmaxl, vv[i].deno) * vv[i].deno;	//最小公倍數:分母
			}
		}
		for (int i = 0; i < n; i++) {
			allmole += (multmaxl / vv[i].deno) * vv[i].mole;	//分子和
		}
		//printf("%d %d\n", allmole, multmaxl);
		if (allmole == 0) {
			printf("0\n");
			continue;
		}
		if ((allmole / multmaxl) == 0) {
			printf("%lld/%lld\n", allmole / gcd(allmole, multmaxl), multmaxl / gcd(allmole, multmaxl));
		}
		else {
			if (allmole % multmaxl == 0) printf("%lld\n", allmole / multmaxl);
			else {
				printf("%lld ", allmole / multmaxl);
				allmole = allmole - (allmole / multmaxl * multmaxl);
				printf("%lld/%lld\n", allmole / gcd(allmole, multmaxl), multmaxl / gcd(allmole, multmaxl));
			}
		}
	}
	return 0;
}