HDU 1316 How Many Fibs?

本文介绍了如何通过打表、大整数运算和二分搜索来解决四星难度的Fibonacci数计算问题,涉及大整数加法、比较和清零操作。
部署运行你感兴趣的模型镜像
/*

推荐题型:四星

题意:输入a、b的值,输出[a,b]之中符合Fib的个数

思路:打表 + 大整数 + 二分搜索
*/
//#define TEST
#include <cstdio>
#include <cstring>
const int nMax = 500;
const int mMax = 105;
struct BigNumber
{
	int data[mMax];
	int len;
	BigNumber(){len = 1; memset(data, 0 ,sizeof(data));}
	BigNumber(char *str){*this = str;}
	BigNumber &operator=(char *str);
	BigNumber operator+(BigNumber &a);
	bool operator<(BigNumber &a);
	void clearLeadZero();
	void print();
}F[nMax];
BigNumber & BigNumber::operator =(char *str)
{
	memset(data, 0, sizeof(data));
	len = strlen(str);
	int i;
	for(i = 0; i < len; ++ i)
		data[i] = str[len - i - 1] - '0';
	return *this;
}
BigNumber BigNumber::operator +(BigNumber &a)
{
	BigNumber z;
	int i, j, q;
	q = 0;
	for(i = 0, j = 0; q || i < len || j < a.len; ++ i, ++ j)
	{
		int p = data[i] + a.data[j] + q;
		z.data[i] = p % 10;
		q = p / 10;
	}
	z.len = i;
	z.clearLeadZero();
	return z;
}
bool BigNumber::operator <(BigNumber &a)
{
	if(len != a.len)
		return len < a.len;
	else
	{
		int i;
		for(i = len - 1; i >= 0; -- i)//②这里曾经出错
			if(data[i] != a.data[i])
				return data[i] < a.data[i];
	}
	return 0;
}
void BigNumber::clearLeadZero()
{
	while(len > 1 && !data[len - 1]) -- len;
}
void BigNumber::print()
{
	int i;
	for(i = len - 1; i >= 0; -- i)
		printf("%d", data[i]);
	printf("\n");
}
bool isZero(int pi)
{
	if(F[pi].data[0] == 0 && F[pi].len == 1)
		return 1;
	return 0;
}
BigNumber &f(int pi)
{
	if(!isZero(pi)) return F[pi];
	if(1 == pi) F[pi] = "1";//①注意看题中给出的条件!
	else if(2 == pi) F[pi] = "2";
	else
		F[pi] = f(pi - 1) + f(pi - 2);
	return F[pi];
}
int lower_bound(BigNumber &a)//③搜索上界、下界只需要一个 < 即可
{
	int left = 1;
	int right = nMax;
	while(left < right)
	{
		int mid = left + (right - left) / 2;
		if(f(mid) < a) left = mid + 1;
		else right = mid;
	}
	return left;
}
int upper_bound(BigNumber &a)
{
	int left = 1;
	int right = nMax;
	while(left < right)
	{
		int mid = left + (right - left) / 2;
#ifdef TEST
		BigNumber temp = f(mid);
		printf("%d ",mid);
		temp.print();
#endif
		if(a < f(mid)) right = mid;
		else left = mid + 1;
	}
	return left;
}
int main()
{
	//freopen("f://data.in", "r", stdin);
	//打表,搜索出n的最大值小于500
	/*
	int T;
	scanf("%d", &T);
	int N;
	while(T--)
	{
		scanf("%d", &N);
		f(N);
		printf("%d\n",F[N].len);
	}
	*/
	//正式程序
	char str1[mMax],str2[mMax];
	BigNumber a, b;
	while(scanf("%s%s", str1, str2) != EOF)
	{
		if('0' == str1[0] && '0' == str2[0])
			//The numbers a and b are given with no superfluous leading zeros,所以只需要判断第一位是否为0即可
			break;
		a = str1;
		b = str2;
		int left = lower_bound(a);
		int right = upper_bound(b);
		printf("%d\n", right - left);
	}
	return 0;
}

您可能感兴趣的与本文相关的镜像

Stable-Diffusion-3.5

Stable-Diffusion-3.5

图片生成
Stable-Diffusion

Stable Diffusion 3.5 (SD 3.5) 是由 Stability AI 推出的新一代文本到图像生成模型,相比 3.0 版本,它提升了图像质量、运行速度和硬件效率

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值