hdu1316 How Many Fibs?(大数)

http://acm.hdu.edu.cn/showproblem.php?pid=1316

How Many Fibs?

Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)
Total Submission(s): 1451    Accepted Submission(s): 604


Problem Description
Recall the definition of the Fibonacci numbers:
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

 

 

code:

#include<iostream>
#include<string>
#include<cmath>
using namespace std;
#define MaxSize 110
#define N 490
struct BigN
{
	int a[MaxSize];
	int len; //保存大数的位数
}f[N];
//打印数列
void start()
{
	int i, j, ch;
	f[1].a[1] = 1;
	f[2].a[1] = 2;
	f[2].len = f[1].len = 1;
	for(i = 3; i < N; i++)
	{
		ch = 0;
		for(j = 1; j <= f[i-2].len; j++)
		{
			
			f[i].a[j] = f[i-1].a[j] + f[i-2].a[j] + ch;
			ch = f[i].a[j] / 10;
			if(f[i].a[j] > 9)
				f[i].a[j] %= 10;
		}
		//较大的数的第一位单独考虑
		if(f[i-1].len > f[i-2].len)
		{
			f[i].a[j] = f[i-1].a[j] + ch;
			ch = f[i].a[j] / 10;
			if(ch > 0)
				f[i].a[j] %= 10;
			j++;			
		}
		//仍有进位时,保存进位
		if(ch > 0)
			f[i].a[j++] = ch;
		f[i].len = j - 1;
	}	
}
//字符串转整型
void CharToInt(string s, int *a)
{
	int i;
	for(i = 1; i < s.length() + 1; i++)
	{
		a[i] = s[s.length() - i] - '0';
	}
}
//比较两大数的大小
int com(int *a, int n)
{
	int i,t;
	for(i = f[n].len; i>=1; i--)
	{
		t = f[n].a[i] - a[i];
		if(t > 0) 
			return 1;
		if(t < 0)
			return -1;
	}
	return 0;
}
int main()
{
	int i;
	string s1, s2;
	start();
	while(cin>>s1>>s2)
	{
		if(s1 == "0" && s2 == "0") break;
		int len1 = s1.length();
		int len2 = s2.length();
		int *a = new int[len1+2];
		int *b = new int[len2+2];
		CharToInt(s1,a);
		CharToInt(s2,b);
		int t1,t2,t3,t4,t,t0;
		t1 = t2 = t3 = t4 = 0;
		//保存与两目标大数长度相同的数的位置
		for(i = 1; i <= N ; i++)
		{
			t = f[i].len - len1;
			t0 = f[i].len - len2;
			if(!t && !t1) t1 = i;
			if(t == 1 && !t2) t2 = i;
			if(!t0 && !t3) t3 = i;
			if(t0 == 1 && !t4) 
			{
				t4 = i;
				break;
			}
		}
		int n = t4 - t1;
		//除去位数相同大小符合条件的数
		for(i = t1; i < t2; i++)
		{
			t = com(a,i);
			if(t == -1)
				n--;
		}
		for(i = t3; i < t4; i++)
		{
			t = com(b,i);
			if(t == 1) 
				n--;
		}
		cout<<n<<endl;
		
		delete[] a;
		delete[] b;
	}
	return 0;
}


 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值