【蓝桥杯】2013年第四届蓝桥杯省赛真题-Java语言B组-4-黄金连分数

标题: 黄金连分数

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

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

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

比较简单的一种是用连分数:
【蓝桥杯】2013年第四届蓝桥杯省赛真题-Java语言B组-4-黄金连分数_第1张图片

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

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

小数点后3位的值为:0.618 小数点后4位的值为:0.6180 小数点后5位的值为:0.61803 小数点后7位的值为:0.6180340

(注意尾部的0,不能忽略)

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

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

显然答案是一个小数,其小数点后有100位数字,请通过浏览器直接提交该数字。 注意:不要提交解答过程,或其它辅助说明类的内容。

分析:

当这个连分数只有一层时,为1/(1+1)=1/2
2层,1/(1+1/2)=2/3
3层,1/(1+2/3)=3/5
…………
不难推出后面的分数依次是5/8、8/13、13/21………………

仔细观察,我们不难发现,这个分数的每一项都是斐波那挈数列(1,1,2,3,5,8,13,21………………)中相邻两项的比值。

所以这个题化为求斐波那契数列中相邻两项的比值

题目要求精确到小数点后100位精度的黄金分割值,用普通的int 型或者double无法表示100位小数,所以要用到BigInteger和BigDecimal。

还有个问题,什么时候才够精确呢?
能够表示出100位小数的时候就是精确的吗?
当然不是。
当然是项数越多越精确,当n/n+1项,n再往上增加,这个比值的小数点后101位是稳定的,也就是不变的,我们可以认为此时前100位是精确的了。

代码:

import java.math.BigDecimal;
import java.math.BigInteger;

public class Main {

    	public static void main(String[] args) {
    		BigInteger a = BigInteger.ONE;//1
    		BigInteger b = BigInteger.ONE;//1
    		//斐波那契数列的迭代形式
    		for (int i = 3; i < 300; i++) {
    			BigInteger tmp = b;
    			b = a.add(b);
    			a = tmp;
    		}
    		//大浮点数的除法
    		BigDecimal divide = new BigDecimal(a,110).divide(new BigDecimal(b,110), BigDecimal.ROUND_HALF_DOWN);
    	    //截取字符串,包括0和小数点共103位,即小数点后有101位
    	    System.out.println(divide.toPlainString().substring(0,103));
    	 }
    }

我们可以在for循环中,对i的值进行试探,以此来确定小数点后101位是否稳定是稳定的。

当i<200时,

0.61803398874989484820458683436563811772030917980576286213544862270526046281890244969233401224637257135

当i<300时,

0.61803398874989484820458683436563811772030917980576286213544862270526046281890244970720720418939113748

当i<400时,

0.61803398874989484820458683436563811772030917980576286213544862270526046281890244970720720418939113748

可见i> 300之后,输出结果的101位已经趋于稳定,四舍五入之后,答案应该是

0.6180339887498948482045868343656381177203091798057628621354486227052604628189024497072072041893911375


  1. BigDecimal简介
    BigDecimal 由任意精度的整数非标度值 和32 位的整数标度 (scale) 组成。如果为零或正数,则标度是小数点后的位数。如果为负数,则将该数的非标度值乘以 10 的负scale 次幂。因此,BigDecimal表示的数值是(unscaledValue × 10-scale)。

  2. public String toPlainString()
    返回不带指数字段的此 BigDecimal 的字符串表示形式。

你可能感兴趣的:(蓝桥杯,算法)