HDU 1316 How Many Fibs?

HDU 1316 How Many Fibs?


Problem Description
Recall the definition of the Fibonacci numbers:
f1 := 1
f2 := 2
fn := fn-1 + fn-2 (n >= 3)

Given two numbers a and b, calculate how many Fibonacci numbers are in the range [a, b].


Input
The input contains several test cases. Each test case consists of two non-negative integer numbers a and b. Input is terminated by a = b = 0. Otherwise, a <= b <= 10^100. The numbers a and b are given with no superfluous leading zeros.


Output
For each test case output on a single line the number of Fibonacci numbers fi with a <= fi <= b.


Sample Input
10 100
1234567890 9876543210
0 0


Sample Output
5
4


二分+大数相加,这题好麻烦啊

思路:

首先算出前480个斐波那契数(第480个斐波那契数的位数101位,满足题目要求的数据范围),然后使用二分查找确定a和b在斐波那契数列的位置,两位置做差,即为中间包含的斐波那契数个数,注意a和b也是斐波那契数时,输出结果特殊处理下。


#include <stdio.h>
#include <iostream>
#include <string.h>
#include <string>
using namespace std;
string fib[500];
string a, b, c;

void add(string &a, string &b, string &c)
{
    int lena = a.length(), lenb = b.length();
    int i, j;
    c = "";
    string t("");
    char ch;
    int up;
    for (up = 0, i = lena - 1, j = lenb - 1; i >= 0 && j >= 0 ; i--, j--)
    {
        ch = a[i] + b[j] - 2*'0' + up;
        up = ch / 10;
        ch %= 10;
        ch += '0';
        t += ch;
    }
    if (i < 0)
    {
        for(; j >= 0; j--)
        {
            ch = b[j] - '0' + up;
             up = ch / 10;
             ch %= 10;
             ch += '0';
             t += ch;
        }
    }
    else if ( j < 0)
    {
        for(; i >= 0; i--)
        {
            ch = a[i] - '0' + up;
             up = ch / 10;
             ch %= 10;
             ch += '0';
             t += ch;
        }
    }
    if (up)
    {
        ch = up + '0';
        t += ch;
    }
    for (i=t.length() - 1; i >= 0 ; i--)
    {
        c += t[i];
    }
}


void FIB()
{
    fib[1] = "1";
    fib[2] = "2";
    for (int i = 3 ; i < 500; i++)
    {
        add(fib[i-1], fib[i-2], fib[i]);
    }
}

int compare(string a, string b)
{
    if (a.size() < b.size())
    {
        return -1;
    }
    else if (a.size() > b.size())
    {
        return 1;
    }
    else
    {
        return a.compare(b);
    }
}

int search(string str)
{
    int left = 0, right = 499, mid;
    while(left <= right)
    {
        mid = (left + right)/2;
        if (compare(fib[mid], str) > 0)
        {
            right = mid - 1; 
        }
        else
        {
            left = mid + 1;
        }
    }
    return right;
}

int main()
{
#ifndef ONLINE_JUDGE
    freopen("1.txt", "r", stdin);
#endif
    int m, n;
    bool flag1, flag2;
    FIB();
    while(1)
    {
        flag1 = flag2 = false; 
        cin >> a >> b;
        if (a == "0" && b == "0") 
        {
            break;
        }
        m = search(a);
        n = search(b);
        if (a == fib[m])
        {
            flag1 = true;
        }
        if (b == fib[n])
        {
            flag2 = true;
        }
    //  cout << m << "   " << n << endl; 
        if (flag1)  cout << n - m + 1<< endl;
        else  cout << n - m << endl;

    }
    return 0;
} 
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值