题目描述
这一次小G想二刷《国王排名》,故把一道题目交给你解决(他才不会告诉你这其实是小G的汇编作业 )。这道题是这样的:给出
n
n
n个分数,求这
n
n
n个分数的和。
输入描述:
第1行输入一个整数
n
n
n,表示有
n
n
n个分数。
随后
n
n
n行,每行输入2个整数
x
,
y
x,y
x,y表示分数
y
x
\frac{y}{x}
xy。
输出描述:
若结果为整数,直接输出整数即可。否则以 x / y x/y x/y形式输出结果的最简分式,其中 y > 0 y > 0 y>0
样例1输入
4
1 2
1 3
4 3
2 3
样例1输出
7/6
样例2输入
3
-2 12
-11 6
0 6
样例2输出
-2
提示:
设
G
C
D
(
x
,
y
)
GCD(x,y)
GCD(x,y)为两个数
x
,
y
x,y
x,y的最大公因数,
L
C
M
(
x
,
y
)
LCM(x,y)
LCM(x,y)为
x
,
y
x,y
x,y的最小公倍数。
有定理:
G
C
D
(
x
,
y
)
∗
L
C
M
(
x
,
y
)
=
x
∗
y
GCD(x,y) * LCM(x,y)= x*y
GCD(x,y)∗LCM(x,y)=x∗y
数据保证
1 ≤ n ≤ 1 0 6 , − 1 0 9 ≤ x , y ≤ 1 0 9 且 y ≠ 0 1\leq n \leq 10^6, -10^9 \leq x,y≤10^9且y \neq 0 1≤n≤106,−109≤x,y≤109且y=0。对于C/C++选手数据保证运算过程中所有数在数值上(若为整数即整数的绝对值,若为分式即分子绝对值和分母的绝对值)都可以不超过某种基本数据类型范围。
题解
每一步模拟手算时分子分母的化简。令
G
C
D
(
x
,
y
)
GCD(x,y)
GCD(x,y)为两个数
x
,
y
x,y
x,y的最大公因数,
L
C
M
(
x
,
y
)
LCM(x,y)
LCM(x,y)为
x
,
y
x,y
x,y的最小公倍数。在求出
G
C
D
(
x
,
y
)
GCD(x,y)
GCD(x,y)后需要用到
G
C
D
(
x
,
y
)
∗
L
C
M
(
x
,
y
)
=
x
∗
y
GCD(x,y) * LCM(x,y)= x*y
GCD(x,y)∗LCM(x,y)=x∗y
来求出
L
C
M
(
x
,
y
)
LCM(x,y)
LCM(x,y),同时尽量避免求
G
C
D
(
x
,
y
)
GCD(x,y)
GCD(x,y)出现负数。尽管输入的分子分母绝对值大小都不超过
1
0
9
10^9
109,但在计算过程中可能出现两个数乘积很大的情况,需要用long long数据类型规避这一问题。
#include<bits/stdc++.h>
#define LL long long
using namespace std;
LL n,x,y,ansx = 0,ansy = 1,GCD,LCM,num = 0;
LL gcd( LL a,LL b )
{
if( b==0 ) return a;
else return gcd( b,a%b );
}
void solve()
{
cin>>n;
for(int i=1;i<=n;i++)
{
cin>>x>>y;
if( i==1 )
{
ansx = x;
ansy = y;
}
else
{
GCD = gcd( ansy , y );
LCM = y * ansy / GCD;//求最小公倍数
ansx = ( ansx*(LCM/ansy) + x*(LCM/y) );
ansy = LCM;
}
GCD = gcd( abs( ansx ) ,ansy );//对最后答案进行化简,同时尽量避免gcd出现负数
if( ansx==0 )//当分子为0时为方便计算直接将分母置为1
{
ansy = 1;
}
else
{
ansx /= GCD;
ansy /= GCD;
}
}
if( ansy==1 ) cout<<ansx;//若化简后分母为1,说明最终答案为整数,直接输出即可
else cout<<ansx<<"/"<<ansy<<endl;
}
int main()
{
solve();
return 0;
}