POJ - 2413 How many Fibs? --- 大数加和模板+二分查找

这个题就是一个普通的二分查找题,但要注意的是此题要结合 大数加和模板 ,大数的题不常见,在这里主要记录一下 大数加和模板。

附上大数加和模板:

//大数加和模板
string bigsum(string s1,string s2)
{
     if(s1.length()<s2.length())
     {
          string temp=s1;
          s1=s2;
          s2=temp;
     }
     for(int i=s1.length()-1,j=s2.length ()-1;i>=0;i--,j--)
     {
          s1[i]=char(s1[i]+(j>=0?s2[j]-'0':0));
          if(s1[i]-'0'>=10)
          {
              s1[i]=char((s1[i]-'0')%10+'0');
              if(i)
                   s1[i-1]++;
              else
                   s1='1'+s1;
          }
     }
     return s1;
}

题目链接:https://vjudge.net/problem/POJ-2413

                                                        How many Fibs?

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

题目大意:判断 a 到 b 之间有多少个斐波那契数列的值。

题目思路:利用大数加和模板对斐波那契数列进行打表,预处理。

之后二分查找a,b在斐波那契数列中的位置。

附上AC代码:

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
#include<map>
#include<set>
#include<stack>
#include<queue>
#include<vector>
#include<string>
#define cla(a, sum) memset(a, sum, sizeof(a))
using namespace std;
typedef long long ll;
const int maxn=605;
string sum[maxn];
//大数加和模板
string bigsum(string s1,string s2)
{
     if(s1.length()<s2.length())
     {
          string temp=s1;
          s1=s2;
          s2=temp;
     }
     for(int i=s1.length()-1,j=s2.length ()-1;i>=0;i--,j--)
     {
          s1[i]=char(s1[i]+(j>=0?s2[j]-'0':0));
          if(s1[i]-'0'>=10)
          {
              s1[i]=char((s1[i]-'0')%10+'0');
              if(i)
                   s1[i-1]++;
              else
                   s1='1'+s1;
          }
     }
     return s1;
}

bool judge(string s1,string s2)
{
    if(s2.size()==s1.size()) {
        if(s2>s1) return true;
    }
    else {
        if(s2.size()>s1.size()) return true;
    }
    return false;
}
//二分查找
int search(string s)
{
    int left=0,right=maxn;             
    while(left<=right)
    {
        int mid=(left+right)>>1;
        if(sum[mid]==s) return mid;
        else {
            if(judge(sum[mid],s)) left=mid+1;          
            else right=mid-1;
        }
    }
    return left;
}

int main()
{
    sum[0]="1";
    sum[1]="2";
    for(int i=2;i<maxn;i++)//打表,预处理 
        sum[i]=bigsum(sum[i-1],sum[i-2]);
    string a,b;
    while(cin>>a>>b)
    {
        if(a=="0"&&b=="0") break;
        int p1=search(a);
        int p2=search(b);
        if(sum[p2]==b) p2++;
        cout<<p2-p1<<endl;
        a.clear();
        b.clear();
    }
}

 

 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值