使用JavaScript解答2018第九届蓝桥杯C/C++省赛A组试题

时间:2022-09-10 14:47:17

大三时参加过第七届蓝桥杯,转眼已经两年,最近看了看第九届蓝桥杯试题,打算用JavaScript实现一下。

题目1

标题:分数

1/1 + 1/2 + 1/4 + 1/8 + 1/16 + ….
每项是前一项的一半,如果一共有20项,
求这个和是多少,结果用分数表示出来。
类似:3/2 。当然,这只是加了前2项而已。分子分母要求互质。
注意:
需要提交的是已经约分过的分数,中间任何位置不能含有空格。请不要填写任何多余的文字或符号。

解答:

以下讨论不使用数学公式,仅使用JavaScript编程解决的方法。

class Question1 {
  constructor () {
    this.result = ''
  }
  // 辅助方法->求两个数的最小公倍数
  lcm (a, b) {
    const minNum = Math.min(a, b)
    const maxNum = Math.max(a, b)
    let temp = 0
    for (let i = minNum; i <= maxNum; i++) {
      temp = minNum * i
      if (temp % maxNum === 0) {
        return temp
        break
      }
    }
  }
  // 辅助方法->求两个数的最大公约数
  gcd (a, b) {
    const minNum = Math.min(a, b)
    const maxNum = Math.max(a, b)
    for (let i = minNum; i > 0; i--) {
      if (maxNum % i === 0 && minNum % i ===0) {
        return i
      }
    }
  }
  // 主方法
  calculate () {
    let a = []
    let numerator = 1
    let denominator = 1
    // 将分数推送进二维数组,第一个元素为分子,第二个元素为分母
    for (let i = 0; i < 20; i++) {
      a[i] = [numerator, denominator]
      denominator *= 2
    }
    // 求所有分母最小公倍数
    let lcmResult = 0
    for (let i = 0; i < a.length; i++) {
      lcmResult = this.lcm(a[i][0], a[i][1])
    }
    // numeratorSum (通分后的分子共和,初始化为0)
    let numeratorSum = 0
    // 分子乘以(最小公倍数/分母),分母都变为lcmResult,即:通分
    for (let i = 0; i < a.length; i++) {
      a[i][0] *= lcmResult / a[i][1]
      a[i][1] = lcmResult
      numeratorSum += a[i][0]
    }
    // 求分子分母最大公约数
    const gcdResult = this.gcd(numeratorSum, lcmResult)
    // 计算结果
    if (gcdResult === 1) {
      this.result =  numeratorSum + '/' + lcmResult
    } else {
      this.result = numeratorSum / gcdResult + '/' + lcmResult / gcdResult
    }
  }
  // 展示结果
  display () {
    console.log('结果为:' + this.result)
  }
}
const obj = new Question1()
obj.calculate()
obj.display()

在node环境执行此js文件,如:node Question1.js,可得到结果为:1048575/524288,如下:
使用JavaScript解答2018第九届蓝桥杯C/C++省赛A组试题
解析请看源码中的注释,请从实例化对象部分(Question1类外)开始阅读。

有空再来做其他题,周末愉快。