PAT Basic 1034. 有理数四则运算

PAT Basic 1034. 有理数四则运算

1. 题目描述:

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

2. 输入格式:

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

3. 输出格式:

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

4. 输入样例:

2/3 -4/2
5/3 0/6

5. 输出样例:

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

6. 性能要求:

Code Size Limit
16 KB
Time Limit
200 ms
Memory Limit
64 MB

思路:

加减乘除运算本身通过整型运算得出结果即可,本题主要涉及到输出的处理。题目要求输出的每个分数必须是最简形式,这里定义了子函数void toSimplest(long num, long denomi)用于输出最简形式的分数,另外定义了四个子函数分别处理加减乘除。

其中分数的整数部分直接通过整型除法得出,主要问题在于真分数的处理,这里要把分子分母的最大公约数消去才能得到最简形式,所以定义了long getGcd(long num1, long num2)用于计算最大公约数,涉及到更相减损法和辗转相除法。

最后就是虽然题目保证分子分母和正确的输出没有超过整型范围的整数,但是运算过程中涉及到两数相乘,所以这里还是需要定义为long类型。

My Code:

#include <stdio.h>

// void toSimplest(int num, int denomi);
// void sum2rational(int num1, int den1, int num2, int den2);
// void minus2rational(int num1, int den1, int num2, int den2);
// void multi2rational(int num1, int den1, int num2, int den2);
// void divid2rational(int num1, int den1, int num2, int den2);
void toSimplest(long num, long denomi);
void sum2rational(long num1, long den1, long num2, long den2);
void minus2rational(long num1, long den1, long num2, long den2);
void multi2rational(long num1, long den1, long num2, long den2);
void divid2rational(long num1, long den1, long num2, long den2);
long getGcd(long num1, long num2);

int main(void)
{
    //toSimplest(-1, 3);
//     int num1, den1, num2, den2;
    long num1, den1, num2, den2;
    
    scanf("%ld/%ld%ld/%ld", &num1, &den1, &num2, &den2);
//     scanf("%d/%d%d/%d", &num1, &den1, &num2, &den2);
    //printf("%d/%d %d/%d\n", num1, den1, num2, den2); // test input correct
    
    sum2rational(num1, den1, num2, den2);
    minus2rational(num1, den1, num2, den2);
    multi2rational(num1, den1, num2, den2);
    divid2rational(num1, den1, num2, den2);
    
    return 0;
}

void toSimplest(long num, long denomi) //(int num, int denomi)
{
    long k = num/denomi; // the integer's part
    long mod = num % denomi; // the numerator of simplest form
    long i, gcd;
//     int k = num/denomi; // the integer's part
//     int mod = num % denomi; // the numerator of simplest form
//     int i, gcd;
    
    if(num < 0) // the fraction is negative
    {
        if(k) // k exist
        {
            //printf("(-%d", k);
            printf("(%ld", k);
            if(mod) // it's a real fraction, mod is negative for num is negative
            {
//                 for(i = -mod; i>=2; i--)
//                 {
//                     if((-mod % i == 0) && (denomi % i == 0))
//                     {
//                         gcd = i;
//                         break;
//                     }
//                 }         
//                 if(i>=2) {mod/=gcd; denomi/=gcd;} //this assure simplest form of fraction.
                if(mod != -1)
                {
                    gcd = getGcd(-mod, denomi);
                    mod /= gcd;
                    denomi /= gcd; 
                }
                
                printf(" %ld/%ld)", -mod, denomi); //this can't assure simplest form
            }
            else // just have integer part
                printf(")");
        }
        else // k not exist, it must a real fraction
        {
//             for(i = -num; i>=2; i--)
//             {
//                 if((-num % i == 0) && (denomi % i == 0))
//                 {
//                     gcd = i;
//                     break;
//                 }
//             }         
//             if(i>=2) {num/=gcd; denomi/=gcd;} //this assure simplest form of fraction
            if(num != -1)
            {
                gcd = getGcd(-num, denomi);
                num /= gcd;
                denomi /= gcd;                
            }
            
            printf("(%ld/%ld)", num, denomi);
        }
    }
    else if(num > 0)// the fraction is positive
    {
        if(k) // k exist
        {
            printf("%ld", k);
            if(mod) // it's a real fraction
            {
//                 for(i = mod; i>=2; i--)
//                 {
//                     if((mod % i == 0) && (denomi % i == 0))
//                     {
//                         gcd = i;
//                         break;
//                     }
//                 }         
//                 if(i>=2) {mod/=gcd; denomi/=gcd;} //this assure simplest form of fraction
                if(mod != 1)
                {
                    gcd = getGcd(mod, denomi);
                    mod /= gcd;
                    denomi /= gcd;                    
                }
                
                printf(" %ld/%ld", mod, denomi);
            }
        }
        else // k not exist, it must a real fraction
        {
//             for(i = num; i>=2; i--)
//             {
//                 if((num % i == 0) && (denomi % i == 0))
//                 {
//                     gcd = i;
//                     break;
//                 }
//             }         
//             if(i>=2) {num/=gcd; denomi/=gcd;} //this assure simplest form of fraction
            if(num != 1)
            {
                gcd = getGcd(num, denomi);
                num /= gcd;
                denomi /= gcd;                
            }
            
            printf("%ld/%ld", num, denomi);
        }
    }
    else // num == 0, first submit neglect this point, casue output format incorrect
    {
        printf("0");
    }
}

void sum2rational(long num1, long den1, long num2, long den2)//(int num1, int den1, int num2, int den2)
{
//     int res_num, res_den;
    long res_num, res_den;
    
    res_num = num1*den2 + den1*num2;
    res_den = den1*den2;
    
    toSimplest(num1, den1);
    printf(" + ");
    toSimplest(num2, den2);
    printf(" = ");
    toSimplest(res_num, res_den);
    printf("\n");
}

void minus2rational(long num1, long den1, long num2, long den2)//(int num1, int den1, int num2, int den2)
{
//     int res_num, res_den;
    long res_num, res_den;
    
    res_num = num1*den2 - den1*num2;
    res_den = den1*den2;
    
    toSimplest(num1, den1);
    printf(" - ");
    toSimplest(num2, den2);
    printf(" = ");
    toSimplest(res_num, res_den);
    printf("\n");
}

void multi2rational(long num1, long den1, long num2, long den2)//(int num1, int den1, int num2, int den2)
{
//     int res_num, res_den;
    long res_num, res_den;
    
    res_num = num1*num2;
    res_den = den1*den2;
    
    toSimplest(num1, den1);
    printf(" * ");
    toSimplest(num2, den2);
    printf(" = ");
    toSimplest(res_num, res_den);
    printf("\n");
}

void divid2rational(long num1, long den1, long num2, long den2)//(int num1, int den1, int num2, int den2)
{
//     int res_num, res_den;
    long res_num, res_den;
    
    res_num = num1*den2;
    res_den = den1*num2;
    
    if(res_den < 0) // to assure the result's denominator sign is postive
    {
        res_den = -res_den;
        res_num = -res_num;
    }
    
    toSimplest(num1, den1);
    printf(" / ");
    toSimplest(num2, den2);
    printf(" = ");
    if(res_den)
        toSimplest(res_num, res_den);
    else
        printf("Inf");
    printf("\n");
}

long getGcd(long num1, long num2) // get the greatest common divisor
{
//     num1 = (num1>0) ? num1 : -num1;
//     num2 = (num2>0) ? num2 : -num2;
    
//     while(num1 != num2)
//     {
//         if(num1 > num2)
//             num1 -= num2;
//         else
//             num2 -= num1;
//     }
//     return num1;
    long temp;
    
    while(temp = num1 % num2) // testpoint3 throw timeout, here use zhanzhuanxiangchu to pass testpoint3
    {
        num1 = num2;
        num2 = temp;
    }
    
    return num2;
}
posted @ 2023-03-20 11:30  十豆加日月  阅读(24)  评论(0编辑  收藏  举报