P 1034 有理数四则运算

转跳点:🐏

1034 有理数四则运算 (20分)
 

本题要求编写程序,计算 2 个有理数的和、差、积、商。

输入格式:

输入在一行中按照 a1/b1 a2/b2 的格式给出两个分数形式的有理数,其中分子和分母全是整型范围内的整数,负号只可能出现在分子前,分母不为 0。

输出格式:

分别在 4 行中按照 有理数1 运算符 有理数2 = 结果 的格式顺序输出 2 个有理数的和、差、积、商。注意输出的每个有理数必须是该有理数的最简形式 k a/b,其中 k 是整数部分,a/b 是最简分数部分;若为负数,则须加括号;若除法分母为 0,则输出 Inf。题目保证正确的输出中没有超过整型范围的整数。

输入样例 1:

2/3 -4/2
 

输出样例 1:

2/3 + (-2) = (-1 1/3)
2/3 - (-2) = 2 2/3
2/3 * (-2) = (-1 1/3)
2/3 / (-2) = (-1/3)
 

输入样例 2:

5/3 0/6
 

输出样例 2:

1 2/3 + 0 = 1 2/3
1 2/3 - 0 = 1 2/3
1 2/3 * 0 = 0
1 2/3 / 0 = Inf

 

  这道题比较麻烦,因为需要考虑的东西较多所以,容易少考虑一些情况。

    1、我们需要考虑两个分数化简之后分母为0的不合法的情况。

    2、存在异号的时候,考虑符号的输出和异号的判断(千万别相乘小于0,这玩意会炸long long都塞不下,除非你想用大数运算,同余模好像也行)

    3、假分数要化成带分数,整数部分记得有空格

    4、括号输出,这玩意和负号共存,置一个flag,为1时输出(-1,最后要结束的时候宅检查一遍flag用于输出 )

    5、要注意PTA上gcc的C评测机的long long只有32位,所以gcc的C怎么提交都会出错(好吧,我比较懒,不想在想其他方法了,这也是我无意之中交错的时候发现的)

第五点是错的,我当时浅显的认为是评测机的问题 U•ェ•*U

大佬们,给个AC的C语言代码呗

AC代码:

 1 #include <stdio.h>
 2 #include <stdlib.h>
 3 #include <math.h>
 4 
 5 long long GCD(long long x, long long y) { return (0 == y) ? x : GCD(y, x % y); }
 6 void Simplify(long long Molecule, long long Denominator);
 7 
 8 int main(void)
 9 {
10 
11     long long DivdMoce, DivdDenom, DivsMoce, DivsDenom;
12 
13     scanf("%lld/%lld %lld/%lld", &DivdMoce, &DivdDenom, &DivsMoce, &DivsDenom);
14    
15     Simplify(DivdMoce, DivdDenom); printf(" + "); Simplify(DivsMoce, DivsDenom); printf(" = "); Simplify(DivdMoce * DivsDenom + DivdDenom * DivsMoce, DivdDenom * DivsDenom); printf("\n");
16     Simplify(DivdMoce, DivdDenom); printf(" - "); Simplify(DivsMoce, DivsDenom); printf(" = "); Simplify(DivdMoce * DivsDenom - DivdDenom * DivsMoce, DivdDenom * DivsDenom); printf("\n");
17     Simplify(DivdMoce, DivdDenom); printf(" * "); Simplify(DivsMoce, DivsDenom); printf(" = "); Simplify(DivdMoce * DivsMoce, DivdDenom * DivsDenom); printf("\n");
18     Simplify(DivdMoce, DivdDenom); printf(" / "); Simplify(DivsMoce, DivsDenom); printf(" = "); Simplify(DivdMoce * DivsDenom, DivdDenom * DivsMoce);
19 
20     return 0;
21 }
22 
23 void Simplify(long long Molecule, long long Denominator)
24 {
25     //分母是否合法
26     if (0 == Molecule * Denominator)
27     {
28         printf("%s", 0 == Denominator ? "Inf" : "0");
29         return;
30     }
31 
32     //正负号判定
33     int flag = ((Molecule > 0 && Denominator < 0) || (Molecule < 0 && Denominator > 0));
34     //先输出符号
35     printf("%s", 0 == flag ? "" : "(-");
36 
37     //去除符号问题,简化最大公约数求取过程
38     Molecule = abs(Molecule);
39     Denominator = abs(Denominator);
40 
41     //获取商,准备输出带分数整数部分
42     long long Interger = Molecule / Denominator;
43     //如果是假分数,那么化为带分数并输出整数部分
44     if (0 != Interger)
45     {
46         printf("%lld", Interger);
47     }
48     //检测能否被整除
49     if (0 == Molecule % Denominator)
50     {
51         if (1 == flag)
52         {
53             printf(")");
54         }
55         return;
56     }
57     //补上带分数正整数部分的空格
58     if (0 != Interger)
59     {
60         printf(" ");
61     }
62 
63     Molecule = Molecule - Denominator * Interger;
64     long long gcd = GCD(Molecule, Denominator);
65 
66     printf("%lld/%lld%s", Molecule / gcd, Denominator / gcd, 1 == flag ? ")" : "");
67 }

  记得用C++提交

 

   刚刚,小姐姐说我太懒了,嗯,赶紧改正,我写了一份C的AC代码,可以用GCC 的 C 交,而且我知道为什么原本的会错了,

上一个版本我用了abs,这个函数只能返回 int 大小的数据,所以返回后导致精度丢失,导致结果错误。

 

这是C语言AC的代码

#include <stdio.h>

long long GCD(long x, long y) { return (0 == y) ? x : GCD(y, x % y); }
long Simplify(long Molecule, long Denominator);

int main(void)
{
    long DivdMoce, DivdDenom, DivsMoce, DivsDenom;
    scanf("%ld/%ld %ld/%ld", &DivdMoce, &DivdDenom, &DivsMoce, &DivsDenom);

    Simplify(DivdMoce, DivdDenom);printf(" + ");Simplify(DivsMoce, DivsDenom);printf(" = ");Simplify(DivdMoce * DivsDenom + DivsMoce * DivdDenom, DivdDenom * DivsDenom);printf("\n");
    Simplify(DivdMoce, DivdDenom);printf(" - ");Simplify(DivsMoce, DivsDenom);printf(" = ");Simplify(DivdMoce * DivsDenom - DivsMoce * DivdDenom, DivdDenom * DivsDenom);printf("\n");
    Simplify(DivdMoce, DivdDenom);printf(" * ");Simplify(DivsMoce, DivsDenom);printf(" = ");Simplify(DivdMoce * DivsMoce, DivdDenom * DivsDenom);printf("\n");
    Simplify(DivdMoce, DivdDenom);printf(" / ");Simplify(DivsMoce, DivsDenom);printf(" = ");Simplify(DivdMoce * DivsDenom, DivdDenom * DivsMoce);
    return 0;
}
/**
 * 非递归版辗转相除法(a>b)
long GCD(long Molecule, long Denominator)
{ //辗转相除法求最大公约数
    long gcd = Molecule % Denominator;
    while (gcd != 0)
    {
        Molecule = Denominator;
        Denominator = gcd;
        gcd = Molecule % Denominator;
    }
    return Denominator;
}
**/
long Simplify(long Molecule, long Denominator)
{
    if (Denominator == 0)
    {
        printf("Inf");
        return 0;
    }

    //符号判断
    int flag = 1;
    //确定符号,取绝对值,避开abs
    if (Denominator < 0)
    {
        Denominator *= -1;
        flag *= -1;
    }
    if (Molecule < 0)
    {
        Molecule = -Molecule;
        flag *= -1;
    }

    if (flag == -1)
    {
        printf("(-");
    }

    //约分为最简分数
    long gcd = GCD(Molecule, Denominator);
    Molecule = Molecule / gcd;
    Denominator = Denominator / gcd;

    if (1 == Denominator)
    { //假分数
        printf("%ld", Molecule);
    }
    else if (Molecule < Denominator)
    { //正常分数
        printf("%ld/%ld", Molecule, Denominator);
    }
    else if (Molecule > Denominator)
    { //带分数
        printf("%ld %ld/%ld", Molecule / Denominator, Molecule % Denominator, Denominator);
    }
    if (flag == -1)
    {
        printf(")");
    }
    return 0;
}

 

 

 

PTA不易,诸君共勉!

posted @ 2020-01-18 23:03  秦_殇  阅读(182)  评论(0编辑  收藏  举报