PAT甲题题解-1088. Rational Arithmetic (20)-模拟分数计算

输入为两个分数,让你计算+,-,*,\四种结果,并且输出对应的式子,分数要按带分数的格式k a/b输出
如果为负数,则带分数两边要有括号
如果除数为0,则式子中的结果输出Inf
模拟题最好自己动手实现,考验细节处理,其它没啥好说的。

#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cstring>

using namespace std;
long long numerator[2];
long long denominator[2];
long long GCD(long long a,long long b){
    a=abs(a);
    b=abs(b);
    if(b==0)
        return a;
    return GCD(b,a%b);

}
struct Fraction{
    long long integer;
    long long numerator;
    long long denominator;
}frac[3];
/**
转化成带分数的形式
*/
void transfer(long long numerator,long long denominator,int i){
    //long long gcd=GCD(numerator,denominator);
    //numerator=numerator/gcd;
    //denominator=denominator/gcd;
    frac[i].integer=numerator/denominator;
    frac[i].numerator=numerator%denominator;
    frac[i].denominator=denominator;
}
/**
输出,如果为负数还要有括号
*/
void print(Fraction f){
    if(f.integer!=0){
        if(f.integer<0)
            printf("(");
        printf("%lld",f.integer);
    }

    if(f.numerator!=0){
        if(f.integer!=0){
            printf(" ");
        }
        //如果前面整数部分为0,则这里需要加(
        else if(f.numerator<0)
            printf("(-");
        //注意,如果是负数,只要整数前面一个‘-‘就可以,所以这里不需要‘-‘
        if(f.numerator>0)
            printf("%lld/%lld",f.numerator,f.denominator);
        else
            printf("%lld/%lld",-f.numerator,f.denominator);
    }
    if(f.integer==0&&f.numerator==0)
        printf("0");
    else if(f.integer<0 || f.numerator<0)
        printf(")"); //末尾补)
}

int main()
{
    long long res;
    scanf("%lld/%lld %lld/%lld",&numerator[0],&denominator[0],&numerator[1],&denominator[1]);
    //先约分
    long long gcd0=GCD(numerator[0],denominator[0]);
    numerator[0]=numerator[0]/gcd0;
    denominator[0]=denominator[0]/gcd0;
    long long gcd1=GCD(numerator[1],denominator[1]);

    numerator[1]=numerator[1]/gcd1;
    denominator[1]=denominator[1]/gcd1;

    long long gcd=GCD(denominator[0],denominator[1]);
    long long lcm=(denominator[0]/gcd)*gcd*(denominator[1]/gcd);
    transfer(numerator[0],denominator[0],0);
    transfer(numerator[1],denominator[1],1);
    //sum
    long long sum=numerator[0]*(lcm/denominator[0])+numerator[1]*(lcm/denominator[1]);
    long long gcd2=abs(GCD(sum,lcm));
    transfer(sum/gcd2,lcm/gcd2,2);
    print(frac[0]);
    printf(" + ");
    print(frac[1]);
    printf(" = ");
    print(frac[2]);
    printf("\n");

    //difference
    sum=numerator[0]*(lcm/denominator[0])-numerator[1]*(lcm/denominator[1]);
    gcd2=abs(GCD(sum,lcm));
    transfer(sum/gcd2,lcm/gcd2,2);
    print(frac[0]);
    printf(" - ");
    print(frac[1]);
    printf(" = ");
    print(frac[2]);
    printf("\n");

    //product
    sum=numerator[0]*numerator[1];
    res=denominator[0]*denominator[1];
    gcd2=abs(GCD(sum,res));
    transfer(sum/gcd2,res/gcd2,2);
    print(frac[0]);
    printf(" * ");
    print(frac[1]);
    printf(" = ");
    print(frac[2]);
    printf("\n");

    //quotient
    print(frac[0]);
    printf(" / ");
    print(frac[1]);
    printf(" = ");
    if(numerator[1]==0){
        printf("Inf\n");
    }
    else{
        sum=numerator[0]*denominator[1];
        res=denominator[0]*numerator[1];
        if(res<0){
            sum=-sum;
            res=-res;
        }

        gcd2=abs(GCD(sum,res));
        transfer(sum/gcd2,res/gcd2,2);

        print(frac[2]);
        printf("\n");
    }

    return 0;
}

时间: 2024-08-08 13:09:25

PAT甲题题解-1088. Rational Arithmetic (20)-模拟分数计算的相关文章

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

PAT甲题题解-1042. Shuffling Machine (20)-模拟

博主欢迎转载,但请给出本文链接,我尊重你,你尊重我,谢谢~http://www.cnblogs.com/chenxiwenruo/p/6789205.html特别不喜欢那些随便转载别人的原创文章又不给出链接的所以不准偷偷复制博主的博客噢~ 给出洗牌次数,以及洗牌的序列规则第i个数shuffles[i]表示要将第i张牌移到第shuffles[i]个 很简单,就是shuffle_seq[shuffles[i]]=start_seq[i]; #include <iostream> #include

PAT甲题题解-1108. Finding Average (20)-字符串处理

求给出数的平均数,当然有些是不符合格式的,要输出该数不是合法的. 这里我写了函数来判断是否符合题目要求的数字,有点麻烦. #include <iostream> #include <cstdio> #include <algorithm> #include <string.h> using namespace std; const int maxn=105; bool islegal(char*str){ int len=strlen(str); int p

PAT甲题题解-1096. Consecutive Factors(20)-(枚举)

题意:一个正整数n可以分解成一系列因子的乘积,其中会存在连续的因子相乘,如630=3*5*6*7,5*6*7即为连续的因子.给定n,让你求最大的连续因子个数,并且输出其中最小的连续序列. 比如一个数可以分解2*3*4*6*7*8,最大的连续个数为3,因为存在两个,输出最小的那个即2*3*4. 首先,一个数如果是合数,那么它的因子必定不会超过sqrt(n)或者sqrt(n)+1.如果为质数,那么只可能为自己,因为题目说了不包括1. 我们先将2~sqrt(n)+1中为n的因子存到factor数组中,

PAT甲题题解-1050. String Subtraction (20)-水题

#include <iostream> #include <cstdio> #include <string.h> #include <algorithm> using namespace std; /* 水题,注意字符范围是整个ASCII编码即可. */ const int maxn=130; int vis[maxn]; char s1[10000+5]; char s2[10000+5]; int main() { gets(s1); //getcha

PAT甲题题解-1073. Scientific Notation (20)-字符串处理

题意:给出科学计数法的格式的数字A,要求输出普通数字表示法,所有有效位都被保留,包括末尾的0. 分两种情况,一种E+,一种E-.具体情况具体分析╮(╯_╰)╭ #include <iostream> #include <cstdio> #include <algorithm> #include <string.h> #include <cmath> #define POSITIVE 1 #define NEGATIVE 2 using names

PAT甲题题解-1112. Stucked Keyboard (20)-(map应用)

题意:给定一个k,键盘里有些键盘卡住了,按一次会打出k次,要求找出可能的坏键,按发现的顺序输出,并且输出正确的字符串顺序. map<char,int>用来标记一个键是否为坏键,一开始的时候都为0,表明所有的键为坏键. 然后遍历每个字符,统计当前字符连续出现的次数cnt,则只要存在cnt%k!=0,则表明为好键,另其map=1. 最后再for一遍字符串,存储坏键字符串和正确字符串,最后输出即可. #include <iostream> #include <cstdio>

PAT甲题题解-1016. Phone Bills (25)-模拟、排序

博主欢迎转载,但请给出本文链接,我尊重你,你尊重我,谢谢~http://www.cnblogs.com/chenxiwenruo/p/6789229.html特别不喜欢那些随便转载别人的原创文章又不给出链接的所以不准偷偷复制博主的博客噢~~ 给出一天24小时内,每个小时内,每分钟的通话费用给出n个记录,on-line表示通话的开始,off-line表示通话的结束如果on-line/off-line没有对应的另一个,忽略即可 先按人名排序,名称一样的按时间排序,这里时间统一按分钟来算,即一天有24

1088. Rational Arithmetic (20)——PAT (Advanced Level) Practise

题目信息 1088. Rational Arithmetic (20) 时间限制200 ms 内存限制65536 kB 代码长度限制16000 B For two rational numbers, your task is to implement the basic arithmetics, that is, to calculate their sum, difference, product and quotient. Input Specification: Each input fi