2018.3.17 模拟赛——(1)无限序列

本文介绍了一种基于斐波那契数列的递归算法,用于计算特定序列中指定区间内数字'1'的个数。通过观察序列变化规律,将问题转化为斐波那契数列求和问题,并提供完整的C++实现代码。

题目大意:

我们按以下方式产生序列:
1、 开始时序列是: “1” ;
2、 每一次变化把序列中的 “1” 变成 “10” ,”0” 变成 “1”。
经过无限次变化,我们得到序列”1011010110110101101…”。
然后询问Q次,求a到b之间1的个数——

解题思路:

首先,观察一波 —— 序列的变化为:
1
10
101
10110
10110101
然后,我们发现Si(第i次变化)=S(i-1)+S(i-2)
就是斐波那契——
然后可以用递归的方法求出从位置1到位置X之间所有的1的个数。

源程序:

#include <cstdio>
#include <iostream>
#define r(i,a,b) for(int i=a;i<=b;i++)
using namespace std;
unsigned long long f[93],f1[93],a,b;
int l,ll,n;
void ycl()
{
    f[0]=f[1]=f1[1]=1;
    f1[0]=0;
    r(i,2,92)
     {
        f[i]=f[i-1]+f[i-2];
        f1[i]=f1[i-1]+f1[i-2];
     }
}
unsigned long long find(unsigned long long a,unsigned long long b)//递归
{
    if (!a) return 0;
    if (a==f[b]) return f1[b];
    else if(a<=f1[b]) return find(a,b-1);
    else return f1[b-1]+find(a-f[b-1],b-2);
}
int main()
{
    ycl();//斐波那契序列
    scanf("%d",&n);
    for (int i=1;i<=n;i++)
    {
        cin>>a>>b;
        //不知道为什么scanf("%llu%llu",&a,&b);不行
        //所以就用cin
        cout<<find(b,92)-find(a-1,92)<<endl;
    }
}

转载于:https://www.cnblogs.com/Juruo-HJQ/p/9306931.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值