How many Fibs?(高精度)

3 篇文章 0 订阅
2 篇文章 0 订阅

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个,感觉高精度的题必须自己动手多操作,细节很多,看别人的代码只要看个思路,细看就不值得了,细节还是自己操作时,一步步调试,

下面的代码写得略拙-_-!,,本来是用二分查找的,楸了半天没楸好,过两天再试试。

特注:### strcmp()函数并不是先比较字符串长度的,而是直接相减 。




AC代码

#include <iostream>
#include <cstdio>
#include <cstring>
using namespace std;
const int maxnlen = 210;
char fib[485][maxnlen];                                        //存放斐波那契数列

void turn(char *a)                                             //定义倒序函数
{
    int L;
    char temp[maxnlen];
    L=strlen(a);
    for(int i=L-1, j=0; i>=0; i--, j++)
        temp[j]=a[i];
    strcpy(a, temp);
    a[L] = '\0' ;
}

void get_fibs()
{
    int pp, i, j;
    strcpy(fib[1], "1");
    strcpy(fib[2], "2");
    for(i=3; i<485; i++)
    {
        pp = 0;
        int L1 = strlen( fib[i-2] );
        int L2 = strlen( fib[i-1] );
        for(j=0; j<L1; j++)
        {
            fib[i][j] = (fib[i-2][j] - '0' + fib[i-1][j] - '0' + pp) % 10 + '0' ;
            pp = (fib[i-2][j] - '0' + fib[i-1][j] - '0' + pp) / 10 ;
        }
        if( L1 < L2 )
            fib[i][j] = (fib[i-1][j] - '0' + pp) + '0' ;
        else if( L1==L2 && pp == 1 )
            fib[i][j] = '1' ;                                   //fib[]中一直是倒序的
    }
    for(int i=1; i<485; i++)
        turn( fib[i] );                                         //转为正序
}


int main()
{
    get_fibs();
    int i, j, k, flag1, flag2, flag=0;
    char a[maxnlen], b[maxnlen];
    while( scanf("%s%s", a, b) )                                           //有待优化的查找!!!
    {
        if( strcmp(a, "0")==0 && strcmp(b, "0")==0 )
            break;

        for(i = 1; i < 500; i++)
        {
            if(strlen(fib[i]) > strlen(a))
            {
                flag1 = i;
                break;
            }
            if(strlen(fib[i]) == strlen(a) && strcmp(fib[i], a) == 0)
            {
                flag1 = i;  flag = 1;
                break;
            }
            if(strlen(fib[i]) == strlen(a) && strcmp(fib[i], a) > 0)
            {
                flag1 = i;
                break;
            }

        }
        for(i = 1; i < 500; i++)
        {
            if(strlen(fib[i]) > strlen(b))
            {
                flag2 = i;
                break;
            }
            if(strlen(fib[i]) == strlen(b) && strcmp(fib[i], b) == 0)
            {

                flag2 = i;
                if(flag == 1)
                    flag2++;
                break;
            }
            if(strlen(fib[i]) == strlen(b) && strcmp(fib[i], b) > 0)
            {
                flag2 = i;
                break;
            }

        }
        printf("%d\n", flag2 - flag1);
    }


    return 0;
}





评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值