zoukankan      html  css  js  c++  java
  • 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
    ");
        return 0;
    }
    View Code
  • 相关阅读:
    windows10装机小记
    Linus Benedict Torvalds hate FUD
    营销文章good
    商城趣聊4
    商城趣聊3
    商城趣聊2
    商城趣聊1
    temp
    学习代码检视方法 (摘自某图片)
    xilinx sdk闪退问题
  • 原文地址:https://www.cnblogs.com/chenxiwenruo/p/6780913.html
Copyright © 2011-2022 走看看