PAT甲题题解-1081. Rational Sum (20)-模拟分数计算
模拟计算一些分数的和,结果以带分数的形式输出
注意一些细节即可
#include <iostream> #include <cstdio> #include <algorithm> #include <cstring> #include <cmath> using namespace std; /* 模拟计算一些分数的和,结果以带分数的形式输出 注意一些细节即可 */ const int maxn=105; const int maxv=50000; //long int范围实际上就是int的范围,sqrt(int)不超过50000 long long numerator[maxn]; //分子 long long denominator[maxn]; //分母 int n; int maxexp[maxv]; int prime[maxv]; int cnt=0; int isprime[maxv]; /* 素数筛选法,筛选出素数 */ void init(){ for(int i=2;i<maxn;i++) isprime[i]=1; isprime[1]=0; for(int i=2;i<maxv;i++){ if(isprime[i]){ prime[cnt++]=i; for(int j=i*2;j<maxv;j+=i) isprime[j]=0; } } } /* 分解质因数,顺便用来求LCM */ void factor(long long val){ for(int i=0;i<cnt && val;i++){ int e=0; while(val%prime[i]==0){ e++; val/=prime[i]; } maxexp[i]=max(maxexp[i],e); //LCM即为各个项的相同质因数取最大次数 } //如果val本身是素数 if(val>1){ prime[cnt]=val; maxexp[cnt]=max(maxexp[cnt],1); cnt++; } } long long GCD(long long a,long long b){ if(b==0) return a; return GCD(b,a%b); } int main() { init(); memset(maxexp,0,sizeof(maxexp)); scanf("%d",&n); for(int i=0;i<n;i++){ scanf("%lld/%lld",&numerator[i],&denominator[i]); factor(denominator[i]); } long long lcm=1; for(int i=0;i<cnt;i++){ for(int j=0;j<maxexp[i];j++) lcm*=prime[i]; } long long sum=0; for(int i=0;i<n;i++){ sum+=numerator[i]*(lcm/denominator[i]); } long long integer=sum/lcm; long long left=sum%lcm; if(integer!=0) printf("%lld",integer); if(left!=0){ if(integer!=0) printf(" "); long long gcd=abs(GCD(left,lcm)); //注意这里要加绝对值,因为GDC(-12,9)=-3 printf("%lld/%lld",left/gcd,lcm/gcd); } //若结果为0 if(integer==0 && left==0) printf("0\n"); return 0; }