练习题:PAT. A1081 || PAT. A1088 ||
分数结构体
struct Fraction {
int up, down; //分子、分母
};
结构体的表示规则:
- 1、使
down
为非负数,如果分数为负,那么令分子up
为负即可; - 2、如果该分数恰为
0
,那么规定其分子为0
,分母为1
; - 3、分子分母没有除了
1
以外的公约数;【每次保存完就化简好】
| 化简规则:
- 1、如果分母
down
为负,那么令分子和分母都变成相反数; - 2、如果分子为
0
,那么令分母为1
; - 3、约分:令分子分母同除以两者绝对值的
最大公约数
!
注意点:
由于分数的乘法和除法过程中可能使分子或分母超过int
型表示范围,因此一般情况下,分子分母应当使用long long
型来存储
具体代码
#include<cstdio>
#include<algorithm>
#include<cmath>
using namespace std;
const int maxn = 110;
struct Fraction {
int up, down;
}frac[maxn];
//最大公约数
int gcd(int a, int b) {
if(a < b) swap(a, b);
if(b == 0) return a;
else return gcd(b, a % b);
}
//化简整理分数
Fraction reduction(Fraction f) {
if(f.down < 0) {
f.up = -f.up;
f.down = -f.down;
}
if(f.up == 0) f.down = 1;
else {
int d = gcd(abs(f.up), abs(f.down)); //若是整数的话,此处就把down化为1了
f.up /= d;
f.down /= d;
}
return f;
}
//分数加法
Fraction add(Fraction a, Fraction b) {
a.up = a.up * b.down + b.up * a.down;
a.down = a.down * b.down;
return reduction(a);
}
//分数减法
Fraction minu(Fraction a, Fraction b) {
a.up = a.up * b.down - b.up * a.down;
a.down = a.down * b.down;
return reduction(a);
}
//分数乘法
Fraction multi(Fraction a, Fraction b) {
a.up *= b.up;
a.down *= b.down;
return reduction(a);
}
//分数除法
Fraction divide(Fraction a, Fraction b) {
//判断除数分子(b.up)是否为零,根据题目返回信息
a.up *= b.down;
a.down *= b.up;
return reduction(a);
}
//输出分数结果
void showResult(Fraction a) {
a = reduction(a); //先化简一下!
if(a.down == 1) printf("%d", a.up); //整数
else if(abs(a.up) > a.down) { //假分数
printf("%d %d/%d", a.up / a.down, abs(a.up) % a.down, a.down);
} else { //真分数
printf("%d/%d", a.up, a.down);
}
}
int main() {
int n;
Fraction sum, temp;
sum.up = 0; sum.down = 1;
scanf("%d", &n); //以求n个分数之和为例
for(int i = 0; i < n; i++) {
scanf("%d/%d", &temp.up, &temp.down);
sum = reduction(add(sum, reduction(temp)));
}
showResult(sum);
printf("\n");
return 0;
}