您的位置:首页 > 其它

HDU 1316 How Many Fibs?

2010-06-12 21:43 387 查看
http://acm.hdu.edu.cn/showproblem.php?pid=1316

题目大意:给你一个区间,[a,b]


a <= b <= 10^100,叫你统计在这个区间内有多少个的斐波那契数。

解题思路:注意到a <= b <= 10^100
,也就是说我们只要打表打到某个斐波那契数的长度为
100
位的表就好,之后给定任何的区间都可以通过搜索表来统计。通过打表,我们可以知道,我们要求的最大的斐波那契数为第
518
个数,所以数组就只要开
520
就好了,剩下的就是大数问题了,大家自己可以解决的啦。

#include <stdio.h>
#include <string.h>
#define size 519
#define LL __int64
const unsigned LL WIDTHMAX=1000000000;
const unsigned int WIDTH = 9;
struct BigInt
{
LL val[15];
int len;
BigInt(){len=0;}
}fib[size];
/*字符串转换为大数*/
BigInt StrToBigInt(char *s)
{
BigInt a;
a.len = 0;
int i = strlen(s);
int j;
__int64 sum = 0;
while ( i>=WIDTH)
{
for (j=i-WIDTH; j<i; j++)
sum = sum * 10 + (s[j] - '0');
a.val[a.len++] = sum;
sum = 0;
i -= WIDTH;
}
if (i > 0)
{
for (int j=0; j<i; j++)
sum = sum * 10 + (s[j] - '0');
a.val[a.len++] = sum;
}
return a;
}
/*大数相加*/
BigInt AddBigInt(const BigInt & a, const BigInt & b)
{
//逆序计算a+b,则从低位开始计算
BigInt c;
LL up = 0;
LL i = 0;
c.len = 0;
while (i<a.len&&i<b.len)
{
c.val[c.len++] = (a.val[i] + b.val[i] + up) % WIDTHMAX;
up = (a.val[i] + b.val[i] + up) / WIDTHMAX;
i++;
}
while (i<a.len)
{
c.val[c.len++] =  (a.val[i] + up) % WIDTHMAX;
up = (a.val[i] + up) / WIDTHMAX;
i++;
}
while (i<b.len)
{
c.val[c.len++] =  (b.val[i] + up) % WIDTHMAX;
up = (b.val[i] + up) / WIDTHMAX;
i++;
}
if (up>0)
c.val[c.len++] = up;
return c;
}
/*比较大小*/
int ComPareBigInt(const BigInt & a, const BigInt & b)
{
int i;
if (a.len > b.len)
return 1;
if (a.len < b.len)
return -1;

for (i=a.len-1; i>=0; i--)
{
if (a.val[i] > b.val[i])
return 1;
if (a.val[i] < b.val[i])
return -1;
}
return 0;   /*相等*/
}
int main()
{
int i,count;
char c[101],d[101];
BigInt a,b;
fib[1].val[0]=fib[1].len=fib[2].len=1;
fib[2].val[0]=2;
/*打表*/
for (i=3;;i++)
{
fib[i] = AddBigInt(fib[i-1],fib[i-2]);
if(fib[i].len>=13)/*此时i = 518*/
break;
}
while (scanf("%s%s",c,d)!=EOF)
{
if(strlen(c)==1&&strlen(d)==1&&c[0]=='0'&&d[0]=='0')
break;
count = 0;
a = StrToBigInt(c);
b = StrToBigInt(d);
for (i=1;;i++)
{
if(ComPareBigInt(fib[i],a)<0)/*小于左边界*/
continue;
if (ComPareBigInt(a,fib[i])<=0&&ComPareBigInt(fib[i],b)<=0)/*夹在两个数之间则统计*/
count++;
else
break;
}
printf("%d/n",count);
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: