PAT 分数运算 (大模拟) - 详细题解

毫无疑问, 这是一道纯粹的模拟题, 没有任何地方有规律可循, 完全模拟数学运算就好了

模拟题一般情况都很复杂, 需要分类讨论, 幸好我们在初高中都已经熟练了分数运算, 这里总结一下, 尤其要把计算机同数学不一样的地方着重处理

(1)加减法

     分母相同, 直接加减            //计算机里整数/整数同数学不同, 可能丢数

     分母不同, 先通分, 再加减, 执行(3)

(2)乘除法

     乘法直接相乘, 执行(3)

     除法先取倒数后相乘, 执行(3)

(3)约分

     a, b分别除以gcd(a, b), 这里尤其要注意负数的情况, 先取绝对值再求

还是WA了好多次, 看来模拟还是要多练练

#include <cstdio>
#include <iostream>
#include <algorithm>
#include <cstring>
#include <string>
#include <stdlib.h>
#include <vector>
#include <queue>
#include <cmath>
using namespace std;
#define ms(x, n) memset(x,n,sizeof(x));
typedef  long long LL;

char op;
int a1, b1, a2, b2;
int a, b; //给出a1/b1 a2/b2, 求a/b

int gcd(int m, int n)
{ //返回m, n最大公约数
    if(m < n) swap(m, n);
    int tmp = m%n;
    while(tmp > 0){
        m = n, n = tmp;
        tmp = m%n;
    }
    return n;
}
int lcm(int m, int n)
{ //返回m, n最小公倍数
    return m*n/gcd(m,n);
}

void reducte()
{ //约分a, b
    int t = gcd(fabs(a), fabs(b)); //防止负数
    a /= t, b /= t;
}
void multiply()
{
    if(op=='/'){
        if(a2 < 0)
            b2 -= 2*b2, a2 += 2*a2; //负数考虑负号问题
        swap(a2, b2);
    }
    a = a1*a2, b = b1*b2;
    reducte();
}
void add()
{ //相加或相减
    if(b1 != b2){
        b = lcm(b1, b2);
        if(op == '+')
            a = b/b1*a1 + b/b2*a2; //通分
        else if(op == '-')
            a = b/b1*a1 - b/b2*a2;
        reducte();
    }
    else{ //坟墓相同无须通分
        if(op=='+')
            a = a1+a2;
        else if(op=='-')
            a = a1-a2;
        b = b1;
        reducte();
    }
}

int main()
{
    while(scanf("%d/%d %d/%d %c",&a1,&b1,&a2,&b2,&op) != EOF){
        if(op == '+' || op == '-')
            add();
        else if(op == '*' || op == '/')
            multiply();
        printf("%d/%d\n",a,b);
    }
	return 0;
}

猜你喜欢

转载自blog.csdn.net/a1097304791/article/details/84031238