时间限制:500MS 内存限制:65536K
提交次数:270 通过次数:16
题型: 编程题 语言: C++;C
Description
给你如下Fibonacci 数的定义: F1 = 1 F2 = 2 Fn = Fn-1 + Fn-2 (n >= 3) 给你两个数a与b,现要求你计算在a与b之间(包括a、b)有多少个Fibonacci 数
输入格式
有多行,每行有两个数a、b,使用空格分隔,a <= b <= 10^100(即最大10的100次方) 最后一行为两个0
输出格式
除了最后一行,其它每一行要求输出在a与b之间的Fibonacci 数的个数,一行一个
输入样例
10 100 1234567890 9876543210 0 0
输出样例
5 4
作者
admin
思路:这道题一早就盯着他了,但是一直以为自己不会做(a,b<=10^100) 被范围吓到了
后来在hdu 中做了一道题http://acm.hdu.edu.cn/showproblem.php?pid=1715,大概题意是给出n,求fb的第n项F(n), n的范围是<1000
前1000项的fb是很大的,有1、2百位,这只能用数组存了,那就可以用高精度加法,把前1000项的fb制成表;
而在这道题中,是给出a ,b 求a到b之间的fb个数,同上面的方法,先打一个前1000项的fb表(大数加法),然后 a,b在表中找位置(大数比较),那么他们之间的个数就是了
#include<cstdio> #include<cstring> char fb[1005][1000];//存储前1000项的fb //高精度比较,返回1表示a>b 返回-1表示a=b 0表示a<b int bcmp(char a[],char b[]) { int i,n,m; n=strlen(a); m=strlen(b); if(n>m) return 1;//先比长度 else if(n<m) return 0; else//长度相同的时候再从高位开始逐一比较 { for(i=0; i<n; i++) { if(a[i]>b[i]) return 1; else if(a[i]<b[i]) return 0; else continue; } } return -1;//全部比较完毕,以上return未生效 就是 a=b } //高精度加法 void bplus(char a[],char b[],int t) { int c[1000],d[1000]; memset(c,0,sizeof(c)); memset(d,0,sizeof(d)); int n,m,i,j,k; i=1; n=strlen(a); m=strlen(b); //字符数组转为整形数组 ,逆置存放 for(k=n-1; k>=0; k--) c[i++]=a[k]-‘0‘; j=1; for(k=m-1; k>=0; k--) d[j++]=b[k]-‘0‘; k=n>m?n:m; for(i=1; i<=k; i++) { c[i+1]+=(c[i]+d[i])/10; c[i]=(c[i]+d[i])%10; } if(c[k+1]) k=k+1; //将整形数组,转化为字符数组存在fb数组 j=0; for(i=k; i>=1; i--) fb[t][j++]=c[i]+‘0‘; } int main() { int i,j; char s1[1000],s2[1000]; memset(fb,‘\0‘,sizeof(fb)); fb[1][0]=‘1‘; fb[2][0]=‘2‘; //打表 for(i=3; i<=1000; i++) bplus(fb[i-2],fb[i-1],i); while(scanf("%s%s",s1,s2)) { int cnt=0; if(!((s1[0]-‘0‘)||(s2[0]-‘0‘))) break; for(i=1; i<=1000; i++) { //查找a的位置 i if(bcmp(fb[i],s1)==-1) { cnt=1; i++; break; } if(bcmp(fb[i],s1)>0) { cnt=0; break; } } for(j=i; j<=1000; j++) if(bcmp(fb[j],s2)<=0) cnt++; else break; printf("%d\n",cnt); } return 0; }
时间: 2024-12-09 09:25:16