蓝桥杯-黄金分割数

  • 题目

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

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

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

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

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

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

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

小数后3位的值为:0.618
小数后4位的值为:0.6180
小数后5位的值为:0.61803
小数后7位的值为:0.6180340
(注意尾部的0)

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

  • 代码

分析知道,相邻两个斐波那契数的比值是随序号的增加而逐渐趋于黄金分割比的,所以可以用这个方法。但是要从第几个开始计算呢?测试代码的时候,我发现从250项开始前100位就不变化了。

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

public class GoldNumber {
    static BigInteger[] mem = new BigInteger[252];

    public static void main(String[] args) {
        //110==>>标度 小数点后的位数
        BigDecimal a = new BigDecimal(f(250),110);
        BigDecimal b = new BigDecimal(f(251),110);
        //接近零的舍入模式。在丢弃某部分之前始终不增加数字(即截短)。注意,此舍入模式始终不会增加计算值的大小。
        BigDecimal c = a.divide(b, RoundingMode.HALF_DOWN);

        System.out.println(c.toPlainString().substring(0,102)); 
    }

    static BigInteger f(int n) {
        if(n==1||n==2)
            mem[n] = new BigInteger(""+n);
        else if(mem[n]==null)
            mem[n] = f(n-1).add(f(n-2));
        return mem[n];
    }
}
  • 结果
0.6180339887498948482045868343656381177203091798057628621354486227052604628189024497072072041893911374

以下引自百度

确切值为(√5-1)/2 ,即黄金分割数。
黄金分割数是无理数,前面的1024位为:
0.6180339887 4989484820 4586834365 6381177203 0917980576
2862135448 6227052604 6281890244 9707207204 1893911374
8475408807 5386891752 1266338622 2353693179 3180060766
7263544333 8908659593 9582905638 3226613199 2829026788
0675208766 8925017116 9620703222 1043216269 5486262963
1361443814 9758701220 3408058879 5445474924 6185695364
8644492410 4432077134 4947049565 8467885098 7433944221
2544877066 4780915884 6074998871 2400765217 0575179788
3416625624 9407589069 7040002812 1042762177 1117778053
1531714101 1704666599 1466979873 1761356006 7087480710
1317952368 9427521948 4353056783 0022878569 9782977834
7845878228 9110976250 0302696156 1700250464 3382437764
8610283831 2683303724 2926752631 1653392473 1671112115
8818638513 3162038400 5222165791 2866752946 5490681131
7159934323 5973494985 0904094762 1322298101 7261070596
1164562990 9816290555 2085247903 5240602017 2799747175
3427775927 7862561943 2082750513 1218156285 5122248093
9471234145 1702237358 0577278616 0086883829 5230459264
7878017889 9219902707 7690389532 1968198615 1437803149
9741106926 0886742962 2675756052 3172777520 3536139362
1076738937 6455606060 5922…

  • 百度的C++代码
//很厉害
#include 
using namespace std;
int main (void)
{
    int d,e=2,i=0,j,k=10,N,m;
    cout<<"请输入黄金分割数位数:\n",cin>>N,N++;
    int *a=new int[2*N],*b=new int[N],*c=new int[2*N];
    while(++i<2*N)
        a[i]=b[i/2]=c[i]=0;
    for(cout<<"0.6",a[b[1]=m=2]=4;--N>1;)
    for(b[m]=e,d=0,j=k;--j+1&&!d;)
    {
        for(c[i=2*m]=j*j%k,e=j*j/k;--i>m-2;e=d/k)
            c[i]=(d=e+b[i-m+1]*j)%k;
        for(i=d=m-1;i<2*m&&a[i]<=c[i];i++)
            (a[i]0:1;
        if(d)
            for(e=j<<1,cout<1+2*m++;--i>m-2;)
                if((a[i]-=c[i])<0)
                a[i]+=k,a[i-1]--;
    }
    delete []a,delete []b,delete []c,cin.ignore(),cin.ignore();
    return 0;
}

你可能感兴趣的:(每日编程一题,算法,蓝桥杯)