ACM复习(8)1143 多少个Fibonacci数

Description
给你如下Fibonacci 数的定义:
F1 = 1
F2 = 2
Fn = Fn-1 + Fn-2 (n >= 3)
给你两个数a与b,现要求你计算在a与b之间(包括a、b)有多少个Fibonacci 数

输入格式
有多行,每行有两个数a、b,使用空格分隔,a <= b <= 10^100(即最大10的100次方)
最后一行为两个0

输出格式
除了最后一行,其它每一行要求输出在a与b之间的Fibonacci 数的个数,一行一个

输入样例
10 100
1234567890 9876543210
0 0

输出样例
5
4


解题思路

看到范围时还是有点懵的,怎么想都没有思路。后来突然想到大整数的题目很多都是打表的,
这道题会不会也是呢?虽然范围确实很吓人。先试试吧,然后打了个表就过了。

先将前1000个Fibonacci数打出来,然后读取输入在表里对比,找到对应的坐标相减就是两个
Fibonacci数之间的Fibonacci数个数。

#include<iostream>
#include<string>

using namespace std;
// 存放fibonacci数的表
string fb[1002];

int getIndex(string &s, int mode);
void calculate(int n, int m);

int main()
{
    string a, b;
    int indexa, indexb;
    fb[1] = "1";
    fb[2] = "2";
    // 打表
    for(int i = 1; i < 1000; i ++)
        calculate(i, i + 1);

    while(cin>> a && cin >> b && b[0] != '0')
    {
        indexa = getIndex(a, 1);
        indexb = getIndex(b, 2);
        cout << indexb - indexa + 1 << endl;
    }
    return 0;
} 

int getIndex(string &s, int mode)
{
    if(mode == 1)
    {
        for(int i = 1; i < 1001; i ++)
        {
            if(s.length() < fb[i].length())
                return i;
            else if(s.length() == fb[i].length())
            {
                if(s <= fb[i])
                    return i;
            }
        }
    }
    else
    {
        for(int i = 1; i < 1001; i ++)
        {
            if(s.length() < fb[i].length())
                return i - 1;
            else if(s.length() == fb[i].length())
            {
                if(s < fb[i])
                    return i - 1;
                else if(s == fb[i])
                    return i;
            }
        }
    }
}
// 大整数加法
void calculate(int n, int m)
{
    int index = m + 1;
    int max = fb[m].length();
    string a(fb[n].rbegin(), fb[n].rend());
    string b(fb[m].rbegin(), fb[m].rend());
    string c;
    // 高位补0对齐
    for(int i = 0; i < fb[m].length() - fb[n].length(); i ++)
        a.append(1, '0');
    int e, t, k;
    e = t = 0;
    for(int i = 0; i < max; i ++)
    {
        k = a[i] - '0' + b[i] - '0' + e;
        t = k % 10;
        e = k / 10;
        c.append(1, t + '0');
    }
    if(e == 1)
        c.append(1, '1');
    k = c.length();
    for(int i = 1; i <= k; i++)
        fb[index].append(1, c[k - i]);
}
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值