Gym 100379C Fibonacci number’s ratio (the hard version) (特征方程)

Gym 100379C

题意:

定义一个新的fibonacci数列:使G(n) = a * G(n - 1) + b * G(n - 2);
求n→∞时,G(n) / G(n-1) 的值(保留小数点后6位精度)。

思路:

分情况讨论(根据a,b,g0,g1是否为0,共计16种情况):

  1. a = 0 且 b = 0 时,一定是NO;
  2. g0 = 0 且 g1 = 0 时,一定是NO;
  3. a = 0 且 b != 0 时;
    3.1. g1 != 0 时 , 答案为a;
    3.2.其余情况NO;
  4. b = 0 且 a != 0 时;
    4.1 g1,g1均不为0 时,数列为

    g0,g1,bg0,bg1,b2g0,b2g1,b3g0......
    可以推出,只有 bg0g0=g1g1 时,答案为 sqrt(b) (g1 * g0 < 0) 或 sqrt(b) (g1 * g0 > 0)
    4.2. 其余情况NO;

  5. 其余情况用特征方程解出特征根,若无解则NO,有解则取与近似解相减绝对值较小的一个。

相关资料

代码:
/*
* @author FreeWifi_novicer
* language : C++/C
*/
#include<cstdio>
#include<iostream>
#include<cstring>
#include<cstdlib>
#include<cmath>
#include<algorithm>
#include<string>
#include<map>
#include<set>
#include<vector>
#include<queue>

using namespace std;

#define clr( x , y ) memset(x,y,sizeof(x))
#define cls( x ) memset(x,0,sizeof(x))
#define mp make_pair
#define pb push_back
typedef long long lint;
typedef long long ll;
typedef long long LL;
double f[105];
int main(){
    double a,b,g1,g0;
    cin >> a >> b >> g0 >> g1;
    if((a == 0 && b == 0) || (g1 == 0 && g0 == 0)){
        cout << "NO" << endl;
        return 0;
    }
    if(b == 0 && a != 0){
        if(g0 != 0 && g1 == 0){
            puts("NO");
        }
        else{
            printf("YES\n%.10f\n",1.0 * a);
        }
        return 0;
    }
    if(a == 0 && b != 0){
        if(g1 != 0 && g0 != 0 && b*g0*g0 == g1*g1){
            int tmp = (g0*g1 > 0)? 1:-1;
            printf("YES\n%.10f\n",1.0*sqrt(b)*(double)tmp);
        }
        else{
            puts("NO");
        }
        return 0;
    }
    if(a != 0 && b != 0){
        double delta = 1.0*a*a + 4.0*b;
        if(delta < 0){
            puts("NO");
            return 0;
        }
        puts("YES");
        double c1 = ( (double)a + 1.0*sqrt(delta) ) / 2.0;
        double c2 = ( (double)a - 1.0*sqrt(delta) ) / 2.0;
        f[1] = g0,f[2] = g1;
        for(int i = 3 ; i <= 100 ; i++) f[i] = a*f[i-1] + b*f[i-2];
        double c = f[30]/f[29];
        if( fabs( c1 - c ) > fabs( c2 - c ) )
            printf("%.10f\n",c2);
        else
            printf("%.10f\n",c1);
        return 0;
    }
    puts("NO");
    return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值