PAT 乙级 1062 最简分数
1. 题目简述及在线测试位置
1.1 给定两个正分数 和 一个正整数,从小到大打印 以正整数为分母 并 介于两个正分数之间的最简分数。最简分数:分子和分母没有公约数
1.2 在线测试位置: 1062 最简分数
2. 基本思路
2.1 通过题目示例 7/18 13/20 12 进行分析:对输入的两个正分数进行通分,很容易得到:360为分母,分子范围 [141, 233] 的分数 介于这两个分数之间;其中以12为分母的分数,分子一定满足 分子%30=0,比如 150/360,据上述思路编写代码
2.2 有两点还需注意:对于输入的两个分数,题目并没有保证 数1一定小于数2;另外,2.1的思路 无法直接处理 分子大于等于分母的情况,比如 1/2 1/1 9,此时需要通过同时放大分子分母解决
if (Nume02 >= Deno02) //deal with the situation: 1/2 1/1 9
{
Nume02 *= DenoMiddle;
Deno02 *= DenoMiddle;
}
if (Nume01 >= Deno01) //deal with the situation: 1/1 1/2 9
{
Nume01 *= DenoMiddle;
Deno01 *= DenoMiddle;
}
3. 完整AC代码
#include <iostream>
using namespace std;
int GCD(int a, int b); //Great Common Divisor
int main()
{
int Nume01, Nume02, Deno01, Deno02, Deno;
int DenoMiddle, Key;
int NumeStart, NumeEnd; bool flag = true;
scanf("%d/%d", &Nume01, &Deno01);
scanf("%d/%d", &Nume02, &Deno02);
scanf("%d", &DenoMiddle);
if (Nume02 >= Deno02) //deal with the situation: 1/2 1/1 9
{
Nume02 *= DenoMiddle;
Deno02 *= DenoMiddle;
}
if (Nume01 >= Deno01) //deal with the situation: 1/1 1/2 9
{
Nume01 *= DenoMiddle;
Deno01 *= DenoMiddle;
}
Deno = Deno01 * Deno02; //Common denominator
NumeStart = Nume01 * Deno02;
NumeEnd = Nume02 * Deno01;
Key = Deno / DenoMiddle; //key=360/12
if (NumeStart > NumeEnd) //maybe NumberOne greater than NumberTwo
{
int tmp = NumeStart;
NumeStart = NumeEnd;
NumeEnd = tmp;
}
for (int i = NumeStart + 1; i < NumeEnd; i++)
{
if (!(i % Key) && flag && GCD(i / Key, DenoMiddle) == 1)
{
cout << i / Key << "/" << DenoMiddle;
flag = false;
}
else if (!(i % Key) && !flag && GCD(i / Key, DenoMiddle) == 1)
cout << " " << i / Key << "/" << DenoMiddle;
}
return 0;
}
int GCD(int a, int b) //辗转相除法
{
int c;
while (a % b)
{
c = a % b;
a = b;
b = c;
}
return b;
}