思路:因为数据规模达到了10^100,所以必须要用大数, 直接用java的大数应该能比较快的A掉,这里我用的是C++ 模拟。
第一步,将斐波那契数 打表,因为增长速度很快,10^100级别的斐波那契数 大概在数列的500左右的样子,
第二步,对输入数据a,b分别在表中二分出其大概所在的位置,这个二分要注意点,因为你要据此计算出答案来,所以必须自己考虑清楚。因为斐波那契数列的个数不多,也可以直接一个一个的看是否在[a,b]区间。
最后,输出个数即可。
#include <iostream>
#include <cstring>
using namespace std;
const int MAX_ = 1001;
int f[MAX_][MAX_];
int M;
void add(int s1[],int s2[],int s3[]) {
int i, *m, maxi, mini;
if(s1[0] > s2[0]) {
maxi = s1[0], mini = s2[0], m = s1;
} else {
maxi = s2[0], mini = s1[0], m = s2;
}
for(i = 1; i <= mini; ++i) {
int t = s1[i] + s2[i] + s3[i];
s3[i] = t%10;
s3[i+1] += t/10;
}
for(; i <= maxi; ++i) {
int t = s3[i] + m[i];
s3[i] = t%10;
s3[i+1] += t/10;
}
if(s3[i] > 0)s3[0] = i;
else s3[0] = maxi;
}
void fun() {
memset(f,0,sizeof(f));
f[1][0] = 1;
f[1][1] = 1;
f[2][0] = 1;
f[2][1] = 2;
for(M = 3; ; ++M) {
add(f[M-1],f[M-2],f[M]);
if(f[M][0] >= 101){break;}
}
}
int judge(int a[], int b[]) {
if(a[0] > b[0])return 1;
else if(a[0] < b[0])return -1;
int maxi = a[0];
for(int i = a[0]; i > 0; --i) {
if(a[i] > b[i])return 1;//a>b
else if(a[i] < b[i])return -1;//a<b
}
return 0;
}
int find(int key[], int p) {
int l, r, mid;
l = 1, r = M;
while(l < r) {
mid = (l + r)/2;
int tmp = judge(key,f[mid]);
if(tmp == 0)return mid;
if(r - l == 1) {
int t1,t2;
t1 = judge(key,f[r]);
t2 = judge(key,f[l]);
if(t1 == 0)return r;
else if(t2 == 0)return l;
if(t1 == -1 && t2 == 1) {//要查的数,在最小的斐波那契数和最大的斐波那契数之间
if(p == 1) {
return r;
} else return l;
}
if(t2 == -1){//不在最大最小之间。
if(p == 1)return l;
else return l - 1;//这样的返回设置就是为了统一一个输出公式. 可以根据自己的想法另行设置.
}
if(t1 == 1){
if(p == 1)return r + 1;
else return r;
}
}
if(tmp == -1) r = mid;
else if(tmp == 1) l = mid;
}
}
int main() {
int n, x[MAX_], y[MAX_], i, j;
string s1,s2;
fun();
while(1) {
cin>>s1>>s2;
if(s1[0] == '0' &&s2[0] == '0')break;
if(s2[0] == '-') {
cout<<"0"<<endl;
continue;
} else if(s1[0] == '-') {
j = 1;
} else j = 0;
if(j == 1) {
memset(x,0,sizeof(x));
x[0] = 1;
} else {
int len = s1.length();
for(i = 0; i < len; ++i) {
x[len - i] = s1[i] - '0';
}
x[0] = s1.length();
}
int len = s2.length();
for(i = 0; i < len; ++i) {
y[len - i] = s2[i] - '0';
}
y[0] = s2.length();
/*int ans=0;
for(i = 1; i <= M; ++i){
if(judge(f[i],y) == 1)break;
if(judge(f[i],x) != -1)ans++;
}
cout<<ans<<endl;*/
if((judge(x,f[M]) == 1 )|| (judge(y,f[1]) == -1))cout<<"0"<<endl;
else {
cout<<find(y,0) - find(x,1) + 1<<endl;
}
}
return 0;
}