本題的要求很簡單,就是求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
其實一開始做這道題時還糾結了很久數據輸入的問題,如何將輸入的分數存儲,之前我們有想到cin可以連續輸入,就像這裏面的cin >> fz >> c >> fm;把分數分成三個部分,數字>>斜槓>>數字,真是慚愧,還想着char去輸入,解決了數據輸入的問題其實問題就比較明朗,分別用兩個數組將分子分母存起來,然後求出分母的最小公倍數,Least common multiple,化簡和求最小公倍數時都要用到最大公約數Maximum common divisor,這兩個方法,如下:
最大公約數Maximum common divisor:
long long gcd(long long a, long long b)
{//求最大公約數
return b == 0 ? a : gcd(b, a%b);
}
不斷的取餘,直到b=0,剩下的a就是公約數,具體可以自己驗證算法
最小公倍數,Least common multiple
要利用到最大公約數,即 lcm=兩數乘積除以最大公約數
long long lcm(long long a, long long b)
{//最小公倍數
return (a*b / gcd(a, b));
}
最後代碼要通過測試,還要考慮很多輸出格式問題,如輸出爲整數時,爲0時,
#include<iostream>
using namespace std;
long long gcd(long long a, long long b)
{//求最大公約數
return b == 0 ? a : gcd(b, a%b);
}
long long lcm(long long a, long long b)
{//最小公倍數
return (a*b / gcd(a, b));
}
int main()
{
int len,num;
cin >> len;
long long *a, *b;
a = (long long *)malloc(len*sizeof(long long));
b = (long long *)malloc(len*sizeof(long long));
long long fz, fm; char c; long long lcm1 = 1, gcd1;
for (int i = 0; i < len; i++)
{
cin >> fz >> c >> fm;
//fz = fz*m + fm*z;
//fm = m*fm;
a[i] = fz;
b[i] = fm;
}
//求出最小公倍數
for (int i = 0; i < len; i++)
{
lcm1 = lcm(lcm1, b[i]);
}
fz = 0; fm = lcm1;
for (int i = 0; i < len; i++)
{
a[i] = lcm1 / b[i] * a[i];
b[i] = lcm1;
fz += a[i];
}
num = fz / lcm1;
fz = fz - num*lcm1;
gcd1 = gcd(fz, lcm1);
if (gcd1)
{
fz = fz / gcd1; fm = lcm1 / gcd1;
if (fz == 0)
cout << num << endl;
else if (num==0)
cout<< fz << "/" << fm << endl;
else
cout << num << " " << fz << "/" << fm << endl;
}
else
{
if (fz==0)
cout << num << endl;
else if (num == 0)
cout << fz << "/" << lcm1 << endl;
else
cout << num << " " << fz << "/" << lcm1 << endl;
}
system("pause");
return 0;
}