JavaScript PAT乙级题解 1062 最简分数

文章描述了一个编程问题,如何在C++中找到两个给定分数之间分母为K的所有最简分数,通过计算最小公倍数、通分和约分步骤来实现。作者提供了详细的解题思路和代码示例。
摘要由CSDN通过智能技术生成

一个分数一般写成两个整数相除的形式: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:注意边界值问题,左右两边都是不包含

思路:

  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)

自己想的思路,可能有点笨拙,但是对了就行

/**
 * 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;
}

 

  • 13
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值