题目大意
给定 n n n 个分数 a i b i \dfrac{a_i}{b_i} biai,并且给出 o p t i opt_i opti,当 o p t i opt_i opti 为 1 1 1 时表示在总数上加上 a i b i \dfrac{a_i}{b_i} biai,当 o p t i opt_i opti 为 2 2 2 时表示在总数上减去 a i b i \dfrac{a_i}{b_i} biai,求最后的总和。
解决
本题模拟即可。
对于两个分数 x 1 y 1 \dfrac{x_1}{y_1} y1x1 和 x 2 y 2 \dfrac{x_2}{y_2} y2x2 相加,我们可以通分,即 x 1 × y 2 y 1 × y 2 \dfrac{x_1 \times y_2}{y_1 \times y_2} y1×y2x1×y2 和 x 2 × y 1 y 2 × y 1 \dfrac{x_2 \times y_1}{y_2 \times y_1} y2×y1x2×y1 相加,结果为 x 1 × y 2 + x 2 × y 1 y 1 × y 2 \dfrac{x_1 \times y_2 + x_2 \times y_1}{y_1 \times y_2} y1×y2x1×y2+x2×y1。
对于两个分数 x 1 y 1 \dfrac{x_1}{y_1} y1x1 和 x 2 y 2 \dfrac{x_2}{y_2} y2x2 相减,同上,即 x 1 × y 2 y 1 × y 2 \dfrac{x_1 \times y_2}{y_1 \times y_2} y1×y2x1×y2 和 x 2 × y 1 y 2 × y 1 \dfrac{x_2 \times y_1}{y_2 \times y_1} y2×y1x2×y1 相减,结果为 x 1 × y 2 − x 2 × y 1 y 1 × y 2 \dfrac{x_1 \times y_2 - x_2 \times y_1}{y_1 \times y_2} y1×y2x1×y2−x2×y1。
除了以上大致解法,我们还要考虑一些特殊情况,例如 6 3 \dfrac{6}{3} 36 这种可以约分的,还有 − 6 − 5 \dfrac{-6}{-5} −5−6 和 6 − 5 \dfrac{6}{-5} −56 这种负号有误的,都需要想到。
赛时代码
#include<bits/stdc++.h>
using namespace std;
namespace IO//感谢出题人给的快读模板
{
char ibuf[(1<<20)+1],*iS,*iT;
#if ONLINE_JUDGE
#define gh() (iS==iT?iT=(iS=ibuf)+fread(ibuf,1,(1<<20)+1,stdin),(iS==iT?EOF:*iS++):*iS++)
#else
#define gh() getchar()
#endif
#define reg register
inline long long read()
{
reg char ch=gh();
reg long long x=0;
reg char t=0;
while(ch<'0'||ch>'9') t|=ch=='-',ch=gh();
while(ch>='0'&&ch<='9') x=x*10+(ch^48),ch=gh();
return t?-x:x;
}
}
using IO::read;
inline long long gcd(long long m,long long n)
{
return n?gcd(n,m%n):m;
}
long long n,a,b,ra,rb,GCD,op;//a为分子,b为分母
int main()
{
n=read(),ra=read(),rb=read(),op=read(),n--;
if(op==2) ra=-1*ra;
while(n--)
{
a=read(),b=read(),op=read();
if(op==1) ra=ra*b+rb*a,rb=rb*b;
else ra=ra*b-rb*a,rb=rb*b;
GCD=gcd(ra,rb),ra/=GCD,rb/=GCD;
}
if(ra*rb<0) ra=-1*abs(ra),rb=abs(rb);
if(ra<0 && rb<0) ra=abs(ra),rb=abs(rb);
if(ra%rb==0) printf("%lld",ra/rb);
else printf("%lld/%lld",ra,rb);
return 0;
}