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】之间有多少个fib数。
分析:对于fib数列,无符号int型数据只能表示44个,64位的无符号int型只能表示92个。
本题有100位,显然需要使用字符串表示大整数,这里主要是大数加法。
为了方便计算,在存放大数时,尾部对齐,前面补0,。
//大数加法的实现
int add(char *res,char *num1,char *num2)
{
int c=0;//进位
int i;
res[127]=0;//字符串结束标志
for(i=126;i>=0;i--)
{
res[i]=num1[i]+num2[i]+c-'0';
if(res[i]>'9')
{
c=1;
res[i]-=10;
}
else
c=0;
}
return c;
//返回值为0,表示数组中的数据有前导0,说明还有空间
//返回值为1,表示数据已经存放到res[0],进位没有地方存放而溢出
}
本题需要将普通的十进制数据转换为大数表示的数据
所有的数据在运算前都要进行转换,数字的尾部与数组的尾部对齐,前面补0
//普通数据转换为大数表示的数据
void trans(char *res,char *z)
{
int left;//z的长度
int i;
for(i=0;i<127;i++)
res[i]='0';
res[127]=0;
for(left=0;left<127;left++)
if(z[left]==0)
break;
for(i=0;i<left;i++)
res[127-left+i]=z[i];
}
AC代码:
#include <stdio.h>
#include <string.h>
//大数加法的实现
int add(char *res,char *num1,char *num2)
{
int c=0;//进位
int i;
res[127]=0;//字符串结束标志
for(i=126;i>=0;i--)
{
res[i]=num1[i]+num2[i]+c-'0';
if(res[i]>'9')
{
c=1;
res[i]-=10;
}
else
c=0;
}
return c;
}
//普通数据转换为大数表示的数据
void trans(char *res,char *z)
{
int left;//z的长度
int i;
for(i=0;i<127;i++)
res[i]='0';
res[127]=0;
for(left=0;left<127;left++)
if(z[left]==0)
break;
for(i=0;i<left;i++)
res[127-left+i]=z[i];
}
int main()
{
//打表,把需要的fib数列全部计算出来,共607个
char fib[1024][128]; //fib数列
char a[128],b[128];//储存题目中的区间
char num1[128],num2[128];//对应a,b的fib个数
char ns[128];//全0
int cnt=2;
trans(fib[0],"1");
trans(fib[1],"2");
trans(ns,"0");
while(add(fib[cnt],fib[cnt-2],fib[cnt-1])==0)
cnt++;
int min,max;
while(1)
{
scanf("%s %s",a,b);
trans(num1,a);
trans(num2,b);
if(strcmp(num2,ns)==0)//结束标志
break;
for(min=cnt-1;min>=0;min--)
if(strcmp(num1,fib[min])>0)
break;
for(max=0;max<cnt;max++)
if(strcmp(num2,fib[max])<0)
break;
printf("%d\n",max-min-1);
}
return 0;
}
还是比较有难度的一道题,思路要清晰,而且写代码时要特别仔细。