本題的要求很簡單,就是求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>
#include<iostream>
#include<string.h>
#include<algorithm>
#include<math.h>
using namespace std;
//gcd()函數,作用主要為求兩個數的最大公約數
long long int gcd(long long int m,long long int n)
{
long long int r=m%n;
while(r)
{
m=n;
n=r;
r=m%n;
}
return n;
}
int main()
{
long long int n;
long long int x[103];
long long int y[103];
while(~scanf("%lld",&n))
{
if(n==0)//如果輸入的分數的個數為0的話,最后輸出的結果也肯定為0
{
printf("0\n");
}
else
{
long long int max1=0;
long long int op=1;//因為要求所有墳墓的最小公倍數,所以讓1與第一個分母求公約數
long long int po;
for(long long int i=0;i<n;i++)
{
scanf("%lld/%lld",&x[i],&y[i]);
po=gcd(op,y[i]);//兩個數的最大公約數
max1=op*y[i]/po;//兩個數的最小公倍數
op=max1;//op表示的是與當前值求公約數的另一個,初始值為1
}
long long int m=0,sum=0,sum1=0;
for(long long int i=0;i<n;i++)
{
m=max1/y[i];//分母擴大的倍數
sum+=x[i]*m;//分子和
}
sum1=max1;
long long int gong=gcd(sum,sum1);//最終的分數要約分
sum=sum/gong;
sum1=sum1/gong;
long long int Zheng =sum/sum1;//分數的整數部分
if(sum-sum1*Zheng==0)
printf("%lld\n",Zheng);//分數只有整數部分的話,直接把整數部分輸出來就行
else
{
if(Zheng==0)
{
printf("%lld/%lld\n",sum,sum1);
}
else
printf("%lld %lld/%lld\n",Zheng,sum-Zheng*sum1,sum1);
}
}
}
return 0;
}