第四届图灵杯->How Many Fibs?(1316)

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
 

题目大意:就是给你两个数,让你输出这两个数之间的斐波那契数的个数

刚看完题目就想,递推+二分定位,区间差加一就搞定,后来看到输入我就惊呆了,10^100,,,没办法,只能用字符串处理了,其实比赛的时候,我们仨还一直执着于找规律2333,用字符串模拟整数处理,是我后来想到的,他俩都放弃了,不过当时时间也不多了,改了几次,运行结果都不对,我也就放弃了QAQ,回去又看起了这道题,看到这么大的数字,我又想到了python(hia hia)三下两下,一气呵成,代码只有17行,思路很简单,刚想提交的时候却发现,根本不能用python提交(吐血)不过这里我还是要贴一下python代码~,还是言归正传吧,用C怎么解决,思路还是没变,照着写python用的思路,我没再写二分,而是一个个比较的,,,不过并没有超时~,思路很简单,就是处理起来有点麻烦,所以当时真的是没耐心debug了(= =)

Python:

l = list()
l.append(0)
l.append(1)
l.append(2)
for i in range(3,481):
	l.append(l[i-1] + l[i-2])
while True:
	a,b = map(int,raw_input().split())
	if a == 0 and b == 0:
		break;
	count = 0
	for i in range(1,481):
		if a <= l[i] and b >= l[i]:
			count += 1;
		elif b < l[i]:
			break;
	print count

C++:

#include <iostream>
#include <cstring>
#include <cstdio>

using namespace std;

const int N = 105;

char fib[500][N];     //存放斐波那契数

void add(int n)       //计算f[n]=f[n-1]+f[n-2]
{
    int l1 = strlen(fib[n-1]),l2 = strlen(fib[n-2]);
    int p = l1-1,q = l2-1;
    int a[N],left = 0;
    for(int i = 0; i < 102; i++)
    {
        a[i] = left;
        if(p >= 0)
            a[i] += fib[n-1][p--] - '0';
        if(q >= 0)
            a[i] += fib[n-2][q--] - '0';
        left = a[i] / 10;
        a[i] %= 10;
    }
    int i;
    for(i = 101; i >= 0; i--)
        if(a[i] != 0)
            break;
    int k = 0;
    while(i >= 0)       //注意a[i]是倒序存入字符串中的
        fib[n][k++] = a[i--] + '0';
    fib[n][k] = '\0';
}
bool cmp(char *a,char *b)  //比较两个斐波那契数的大小
{
    int l1 = strlen(a),l2 = strlen(b);
    if(l1 > l2)
        return true;
    if(l1 < l2)
        return false;
    int i = 0;
    while(i < l1)
    {
        if(a[i]-'0' > b[i]-'0')
            return true;
        if(a[i]-'0' < b[i]-'0')
            return false;
        i++;
    }
    return true;
}
int main()
{
    char a[N],b[N];
    strcpy(fib[1],"1");
    strcpy(fib[2],"2");
    for(int i = 3; i <= 480; i++)   //递推到480就可以了,字符串的长度就已经到100多了
        add(i);
    while(~scanf("%s%s",a,b))
    {
        if(strcmp(a,"0")  == 0 && strcmp(b,"0") == 0)
            return 0;        
        int count = 0;
        for(int i = 1; i <= 480; i++)
        {
            if(cmp(fib[i],a) && cmp(b,fib[i]))
                count ++;
            else if(cmp(b,fib[i]) == false)
                break;
        }
        cout << count << "\n";
    }
    return 0;
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值