毫无疑问, 这是一道纯粹的模拟题, 没有任何地方有规律可循, 完全模拟数学运算就好了
模拟题一般情况都很复杂, 需要分类讨论, 幸好我们在初高中都已经熟练了分数运算, 这里总结一下, 尤其要把计算机同数学不一样的地方着重处理
(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;
}