蓝桥杯:黄金连分数

目录

         题目描述

题目分析:

AC代码(Java):

                答案是:


题目描述

本题为填空题,只需要算出结果后,在代码中使用输出语句将所填结果输出即可。

黄金分割数 0.61803... 是个无理数,这个常数十分重要,在许多工程问题中会出现。有时需要把这个数字求得很精确。

对于某些精密工程,常数的精度很重要。也许你听说过哈勃太空望远镜,它首次升空后就发现了一处人工加工错误,对那样一个庞然大物,其实只是镜面加工时有比头发丝还细许多倍的一处错误而已,却使它成了“近视眼”!!

言归正传,我们如何求得黄金分割数的尽可能精确的值呢?有许多方法。

比较简单的一种是用连分数:

                  1
    黄金数 = ---------------------
                        1
             1 + -----------------
                          1
                 1 + -------------
                            1
                     1 + ---------
                          1 + ...

这个连分数计算的“层数”越多,它的值越接近黄金分割数。

请你利用这一特性,求出黄金分割数的足够精确值,要求四舍五入到小数点后 100位。

小数点后3位的值为:0.618;

小数点后4位的值为:0.6180;

小数点后5位的值为:0.61803;

小数点后7位的值为:0.6180340。 (注意尾部的 0,不能忽略)

你的任务是:写出精确到小数点后 100 位精度的黄金分割值。

注意:尾数的四舍五入! 尾数是 0 也要保留!

题目分析:

        求黄金分割率的精度,首先我们要知道的斐波那契数列,他的N越大,前一项和当前项的比值越接近黄金分割。所以我们需要尽可能的扩大斐波那契的N。斐波那契的递增是指数级别的,递增很快,而且题目要求的精度也非常大,所以我们一律考虑用大数来运算(Java的BigInteger和BigDecimal)。

        首先是扩大斐波那契的N项,直接通过An = A(n-1)+A(n-2)即可完成扩大。

        然后就是将他们转换成BigDecimal来进行运算即可,记得精度是保留100位,要四舍五入。

AC代码(Java):

import java.util.Scanner;
import java.math.*;
// 1:无需package
// 2: 类名必须Main, 不可修改

public class Main {
    public static void main(String[] args) {
        //百位小数,直接确定用大数来计算了,Java的BigDecimal用来对超过16位有效位的数进行精确的运算
        //先用BigInteger 确认出分子和分母,然后进行相除
        BigInteger fenzi = new BigInteger("1");
        BigInteger fenmu = new BigInteger("1");
        //斐波那契数列又叫黄金分割数列
        //n越大,就越逼近0.618,所以我们让n尽可能的大
        for(int i = 1;i<10000;i++){
          //An = A(n-1)+A(n-2);
          //所以分子是A(n-1),分母是A(n-2)
          BigInteger temp = fenzi.add(fenmu);
          //然后分母变成了分子,temp是下一个分母
          fenzi = fenmu;
          fenmu = temp;
        }
        //找到斐波那契数列大的N项之后进行小数部分处理
        BigDecimal oneHundred = new BigDecimal("0");
        //将分子和分母也转换成BigDecimal
        BigDecimal fz = new BigDecimal(fenzi);
        BigDecimal fm = new BigDecimal(fenmu);
        // public BigDecimal divide(BigDecimal divisor, int scale, int roundingMode)
        //divisor是除数,scale是精确度,roundingMode是结果的取值方式。
        /*
        BigDecimal.setScale()方法用于格式化小数点
        setScale(1)表示保留一位小数,默认用四舍五入方式 
        setScale(1,BigDecimal.ROUND_DOWN)直接删除多余的小数位,如2.35会变成2.3 
        setScale(1,BigDecimal.ROUND_UP)进位处理,2.35变成2.4 
        setScale(1,BigDecimal.ROUND_HALF_UP)四舍五入,2.35变成2.4
        setScaler(1,BigDecimal.ROUND_HALF_DOWN)四舍五入,2.35变成2.3,如果是5则向下舍
        */
        //意思是 fz/fm,保留100位小数,四舍五入
        oneHundred = fz.divide(fm,100,BigDecimal.ROUND_HALF_DOWN);
        System.out.println(oneHundred.toString());
    }
}

答案是:

        0.61803398874989484820458683436563811772030917980576286213544862

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值