黄金连分数【大数】

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

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


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

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

 

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

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

小数点后3位的值为:0.618
小数点后4位的值为:0.6180
小数点后5位的值为:0.61803
小数点后7位的值为:0.6180340
(注意尾部的0,不能忽略)

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

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

 

黄金分割书  = F[i] / F[i + 1]

 

模拟大数加法和除法就行了

 

代码:

  1 #include <iostream>
  2 #include <cstdio>
  3 #include <cstring>
  4 #include <cmath>
  5 using namespace std;
  6 
  7 const int maxn = 1005;
  8 int f[maxn][505];
  9 
 10 void init() {
 11     f[1][0] = f[2][0] = 1;
 12     for(int i = 3; i <= 1000; i++) {
 13         for(int j = 0; j <= 500; j++) {
 14             f[i][j] = f[i - 1][j] + f[i - 2][j];
 15         }
 16         for(int j = 0; j <= 500; j++) {
 17             if(f[i][j] >= 10) {
 18                 f[i][j + 1] += f[i][j] / 10;
 19                 f[i][j] %= 10;
 20             }
 21         }
 22     }
 23 }
 24 int cnt;
 25 int a[maxn], b[maxn];
 26 int l1, l2;
 27 
 28 bool S(int x) {
 29     int c[maxn] = { 0 };
 30     for(int i = 1; i <= x; i++) {
 31         c[i] = a[i];
 32     }
 33 //    for(int i = 0; i <= x; i++) {
 34 //        printf("%d", c[i]);
 35 //    } puts("**");
 36     for(int i = x, j = l2; j >= 1; i--, j--) {
 37         c[i] -= b[j];
 38     }
 39     for(int i = x; i >= 1; i--) {
 40         if(c[i] < 0) {
 41             c[i - 1]--;
 42             c[i] += 10;
 43         }
 44     }
 45 //    for(int i = 1; i <= x; i++) {
 46 //        printf("%d", c[i]);
 47 //    } puts("##");
 48 
 49     if(c[0] < 0) {
 50         return false;
 51     } else {
 52         for(int i = 1; i <= x; i++) {
 53             a[i] = c[i];
 54         }
 55         return true;
 56     }
 57 }
 58 
 59 int ans[maxn];
 60 int main() {
 61     init();
 62     memset(a, 0, sizeof(a));
 63     memset(b, 0, sizeof(b));
 64     l1 = 500, l2 = 500;
 65     for(int j = 500; j >= 0; j--) {
 66         if(f[999][j] != 0) {
 67             l1 = j;
 68             break;
 69         }
 70     }
 71     cnt = 1;
 72     for(int j = l1;j >= 0; j--) {
 73         a[cnt++] = f[999][j];
 74     }
 75     for(int j = 500; j >= 0; j--) {
 76         if(f[1000][j] != 0) {
 77             l2 = j;
 78             break;
 79         }
 80     }
 81     cnt = 1;
 82     for(int j = l2; j >= 0; j--) {
 83         b[cnt++] = f[1000][j];
 84     }
 85     cnt = 0;
 86     l1 = 500;
 87 //    for(int i = 1; i <= 6; i++) {
 88 //        a[i] = i + 1;
 89 //    }
 90 //    for(int i = 1; i <= 3; i++)  {
 91 //        b[i] = i;
 92 //    }
 93 //    l2 = 3; l1 = 6;
 94 //    for(int i = 1; i <= l1; i++) {
 95 //        printf("%d", a[i]);
 96 //    } puts("");
 97 //    for(int i = 1; i <= l2; i++) {
 98 //        printf("%d", b[i]);
 99 //    } puts("");
100     for(int i = l2; i <= 500; i++) {
101         int nn = 0;
102         while(S(i)) {
103             nn++;
104         }
105         ans[cnt++] = nn;
106     }
107 //    for(int i = 0; i < cnt; i++) {
108 //        printf("%d", ans[i]);
109 //    } puts("");
110     printf("0.");
111     for(int i = 1; i <= 100; i++) {
112         printf("%d", ans[i]);
113     } puts("");
114 }
View Code

 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值