题目:
The good old fibonacci. |
Time Limit:1000MS Memory Limit:65536KB
Total Submit:30 Accepted:10
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 therange [a,b].
Input
The input contains several test cases. Each test case consists of twonon-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 leadingzeros.
Output
For each test case output on a single line the number of Fibonacci numbers fiwith a<=fi<=b.
Sample Input
10 100
1234567890 9876543210
0 0
Sample Output
5
4
题目分析:
初看这题感觉数据量很大,没有思路,后来看了网上的分析才恍然大悟。其实这是可以仔细分析的。此数列是前两项的累加,所以是成比例增长的。10^100约=2^330;同理本数列只需计算出前一千项内应该可以大于10^100;可以通过大整数的加法,通过代码验证实际上第480项就超过100位了。然后只要通过二分查找就可以得出答案了,由于数据量不大也可以直接遍历。
总结:
本题主要考察大整数的加法和大小比较,(二分查找非必须),真正弄明白了就不难了。
主要是要善于分析问题,不要被问题复杂的表面迷惑。同时在本题我还范了一个很低级的错误,习惯性意味数列第二项是1,其实本题是2,导致狂wa了无数次,以后审题要更仔细,避免惯性思维。
代码:
#include <iostream>
#include <cstdio>
#include <cstring>
#include <cmath>
#include <string>
#include <vector>
#include <map>
#include <algorithm>
using namespace std;
struct Num //大整数类,已经写过多次了。
{
int num[1000]={};
Num(){memset(num,0,sizeof(num));}
Num(const string &s)
{
int k=0;
int len=s.size();
for(int i=len-1;i>=0;--i)
{
num[k++]=(s[i]-'0');
}
}
void print() //输出大整数,主要用于测试。
{
int i;
for(i=999;i>=0;--i)
{
if(num[i])
break;
}
for(;i>=0;--i)
{
printf("%d",num[i]);
}
printf("\n");
}
};
Num operator+(const Num &a,const Num &b) //大整数的加法,通过运算符重载,写起来更//简洁。
{
Num c;
int i;
for(i=0;i<1000;++i)
{
c.num[i]=a.num[i]+b.num[i];
}
for(i=0;i<999;++i)
{
c.num[i+1]+=c.num[i]/10;
c.num[i]%=10;
}
return c;
}
int cmp(const Num &a,const Num &b) //比较两个大整数的大小
{
int i,len_a,len_b;
for(i=999;i>=0;--i)
{
if(a.num[i])
break;
}
len_a=i;
for(i=999;i>=0;--i)
{
if(b.num[i])
break;
}
len_b=i;
if(len_a>len_b)
return 1;
else if(len_a<len_b)
return -1;
else
{
for(i=len_a;i>=0;--i)
{
if(a.num[i]>b.num[i])
return 1;
else if(a.num[i]<b.num[i])
return -1;
}
}
return 0;
}
int main()
{
Num f[488];
int i;
f[1]={"1"};f[2]={"2"};
for(i=3;i<488;++i)
f[i]=f[i-1]+f[i-2];
string a,b;
while(cin>>a>>b,a!="0" || b!="0")
{
int l=0,r=0;
Num x={a},y={b};
for(i=1;i<488;++i)
{
if(cmp(f[i],x)>=0)
{
l=i;
break;
}
}
for(i=487;i>=1;--i)
{
if(cmp(f[i],y)<=0)
{
r=i;
break;
}
}
if(r>=l)
cout<<r-l+1<<endl;
else
cout<<"0"<<endl;
}
return 0;
}