How Many Fibs? HDU - 1316

How Many Fibs?

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


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
 

Source
 

Recommend
Eddy
 
(题目转自HDU http://acm.hdu.edu.cn/showproblem.php?pid=1316)


解题思路

在这里我觉得核心的知识是大数加法(前面我有一篇大菲波数的文章~如果有兴趣也可以看一下哦~)


然后我觉得比较有趣的就是大数之间应该怎么比较大小?


我的思路本来是想重载一下运算符。。。。。。但是我目前还没有学到,所以我定义了两个新函数

largerTA(larger than A的简称)和smallerTB(smaller than B)

但其实根据题目应该是不小于不大于。。。。。。没关系,核心的东西没有错。

首先我们要明确一个概念,大数是一个字符串,所以我们比较大小,首先可以从字符串长度开始入手

如果字符串A长度比字符串B的长度要长,那么肯定会A大,反之同理。

如果字符串A的长度和字符串B的长度一样长,那么我们就可以直接用>,<,>=,<=这样的符号来判断,这样子的判断依据是,

从第一位开始判断,根据ascii码判断,看哪个比较大,如果一样,则不断的向后一位一位比较。(这里好像其实也是用到了运算符重载,不过是前辈们已经写好的了)


核心代码

bool largerTA(string a,string b)
{
	if(b.size()>a.size())
	return true;
	if(b.size()<a.size())
	return false;
	if(b.size()==a.size())
	{
		if(b>=a)
		return true;
		else
		return false;
	}
}
bool smallerTB(string a,string b)
{
	if(a.size()<b.size())
	return true;
	if(a.size()>b.size())
	return false;
	if(b.size()==a.size())
	{
		if(a<=b)
		return true;
		else
		return false;
	}
}

代码展示


#include<iostream>
#include<string>
using namespace std;
string add(string s1,string s2)
{
	string s;
	int len1=s1.size()-1;
	int len2=s2.size()-1;
	int sum=0;
	int flag=0;
	while(len1>=0&&len2>=0)
	{
		sum=flag+s1[len1]-'0'+s2[len2]-'0';
		s=s+char(sum%10+'0');
		flag=sum/10;
		len1--;
		len2--;
	}
	while(len1>=0)
	{
		sum=flag+s1[len1]-'0';
		s=s+char(sum%10+'0');
		flag=sum/10;
		len1--;
	}
	while(len2>=0)
	{
		sum=flag+s2[len1]-'0';
		s=s+char(sum%10+'0');
		flag=sum/10;
		len2--;
	}
	if(flag>0)
	{
		s=s+char(flag+'0');
	}
	//s转置
	char tmp=' ';
	int end=s.size(); 
	for(int i=0;i<end/2;i++)
	{
		tmp=s[i];
		s[i]=s[s.size()-i-1];
		s[s.size()-i-1]=tmp;
	}
	return s;
}
bool largerTA(string a,string b)
{
	if(b.size()>a.size())
	return true;
	if(b.size()<a.size())
	return false;
	if(b.size()==a.size())
	{
		if(b>=a)
		return true;
		else
		return false;
	}
}
bool smallerTB(string a,string b)
{
	if(a.size()<b.size())
	return true;
	if(a.size()>b.size())
	return false;
	if(b.size()==a.size())
	{
		if(a<=b)
		return true;
		else
		return false;
	}
}
int main()
{
	string a;
	string b;
	string s[1000];
	s[1]="0";
	s[2]="1";
	while(cin>>a)
	{
		int sum=0;
		cin>>b;
		if(a=="0"&&b=="0")
		break;
		else
		{
			for(int i=3;;i++)
			{
				s[i]=add(s[i-1],s[i-2]);
				if(largerTA(a,s[i])&&smallerTB(s[i],b))
				sum++;
				if(!smallerTB(s[i],b))
				break;
			}
		}
		cout<<sum<<endl;
	}
}


评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值