一个分数一般写成两个整数相除的形式:N/M,其中 M 不为0。最简分数是指分子和分母没有公约数的分数表示形式。
现给定两个不相等的正分数 N1/M1 和 N2/M2,要求你按从小到大的顺序列出它们之间分母为 K 的最简分数。
输入格式:
输入在一行中按 N/M 的格式给出两个正分数,随后是一个正整数分母 K,其间以空格分隔。题目保证给出的所有整数都不超过 10000。
输出格式:
在一行中按 N/M 的格式列出两个给定分数之间分母为 K 的所有最简分数,按从小到大的顺序,其间以 1 个空格分隔。行首尾不得有多余空格。题目保证至少有 1 个输出。
输入样例:
7/18 13/20 12
输出样例:
5/12 7/12
题解如下:
20/20
case2:注意边界值问题,左右两边都是不包含
思路:
- 将三个分母求最小公倍数(12,20,18最小公倍数180)
- 对两个分数进行通分,求出分子范围(7*180/18,13*180/20)
- 分子为这个范围内的180/12的倍数,得到一些符合条件的数字(75,100,115),将其除以180/12(5,6,7)
- 再将这些数字与12进行约分,如果无法约分,则这些数字是符合条件的(5,7),否则不符合条件(2)
自己想的思路,可能有点笨拙,但是对了就行
/**
* 2024/04/15
* 13/20
* 思路:
* 1. 将三个分母求最小公倍数(12,20,18最小公倍数180)
* 2. 对两个分数进行通分,求出分子范围(7*180/18,13*180/20)
* 3. 分子为这个范围内的180/12的倍数,得到一些符合条件的数字(75,100,115),将其除以180/12(5,6,7)
* 4. 再将这些数字与12进行约分,如果无法约分,则这些数字是符合条件的(5,7),否则不符合条件(2)
*/
const readline = require("readline");
const rl = readline.createInterface({
input: process.stdin,
output: process.stdout,
});
let rows = [];
let arr = [];
rl.on("line", function (data) {
arr = data.split(" ");
// 求min/max
let first = arr[0].split("/");
let second = arr[1].split("/");
let max, min;
if (first[0] / first[1] < second[0] / second[1]) {
max = second;
min = first;
} else {
max = first;
min = second;
}
let mid = getMinMultiple(max[1], min[1]);
let after = getMinMultiple(arr[2], mid);
max = max.map((v) => (v * after) / max[1]);
min = min.map((v) => (v * after) / min[1]);
// 求出比min大的第一个最小的15的倍数
let i = min[0] - (min[0] % (after / arr[2])) + after / arr[2];
let resArr = [];
for (i; i < max[0]; i += after / arr[2]) {
resArr.push(i / (after / arr[2]));
}
resArr = resArr.filter(getMaxDivisor);
resArr = resArr.map((v) => `${v}/${arr[2]}`);
console.log(resArr.join(" "));
});
/**
* 求最小公倍数
* @param first 第一个数
* @param second 第二个数
* @returns {number}
*/
function getMinMultiple(first, second) {
let a = first;
let b = second;
let c = first * second;
if (a < b) {
let r = a;
a = b;
b = r;
}
while (true) {
let r = a % b;
if (r === 0) {
return c / b;
} else {
a = b;
b = r;
}
}
}
/**
* 用辗转相除法判断是否可以约分
* @param first 分子
* @returns {boolean}
*/
function getMaxDivisor(first) {
let mid1 = first;
let mid2 = arr[2];
let mid3 = 0;
for (let i = 0; i < i + 1; i++) {
mid3 = mid1 % mid2;
if (mid3 === 0) {
break;
} else {
mid1 = mid2;
mid2 = mid3;
}
}
return mid2 === 1;
}