sjtu oj 1017 二哥养兔子 斐波那契类似问题及大数字的应用

1017. 二哥养兔子

Description

二哥培养出了一种繁殖能力很强的兔子。

这种兔子在出生后的第一个月,能够生出a对兔子;第二个月,能够生出b对兔子;第三个月以及以后的每个月,都可以生出c对兔子。

二哥对此很感兴趣,若他有一对刚出生的兔子,按照最理想的模式繁殖,并假设兔子不死,二哥想知道最少需要几个月这些兔子可以遍布地球的每个角落。

为了回答这个问题,二哥想要知道这种兔子在第N个月时的对数。

Input Format

输入只有一行,四个数,分别为a,b,c,N ( 0abc100,N1000  ),其含义为题目所述。

Output Format

输出只有一个数,为第N个月兔子的对数。

Sample Input

0 1 1 11

Sample Output

144

题目所给的数据为斐波那契数列,对于兔子问题,大家自行百度斐波那契 兔子问题即可明白,这里有这样一个表达式:

res[i]=res[i-3]*c+(res[i-2]-res[i-3])*b+(res[i-1]-res[i-2])*a+res[i-1];

比如第4个月的兔子数,为第一个月的兔子生下的res[1]*c,和第二个月的新生兔子乘以b,加上第三个月新生兔子乘以a再加上这之前的老兔子数即可。

但是这里其实更麻烦的一点是对于大数字的处理,由于N在1000的时候已经远远大于正常的表达范围,所以必须自己用类模仿大数字。

#include <iostream>
#include "string.h"
using namespace std;

class bigInt
{
    friend bigInt operator+(bigInt a,bigInt b);
    friend bigInt operator-(bigInt a,bigInt b);
    friend bigInt operator*(bigInt a,bigInt b);
public:
    int ans[3000];
    int length;
    bigInt()
    {
        memset(ans,0,sizeof(int)*1000);
        length=0;
    }
    bigInt(int a)
    {
        memset(ans,0,sizeof(int)*1000);
        int i=0;
        while(a!=0)
        {
            ans[i++]=a%10;
            a=a/10;
        }
        length=i;
    }
    bigInt(const bigInt& a)
    {
        length=a.length;
        for(int i=0;i<length;i++)
        {
            ans[i]=a.ans[i];
        }
    }
    bigInt& operator=(const bigInt &a)
    {
        if(&a==this) return (*this);
        length=a.length;
        for(int i=0;i<length;i++)
        {
            ans[i]=a.ans[i];
        }
        return (*this);
    }
    void print()
    {
        for(int i=length-1;i>=0;i--)
        {
            cout<<ans[i];
        }
        cout<<endl;
    }


};
bigInt operator*(bigInt a,int b)
{
    bigInt c;
    int carry=0;
    for(int i=0;i<a.length;i++)
    {
        int tp=a.ans[i]*b+carry;
        carry=tp/10;
        c.ans[i]=tp%10;
    }
    int j=a.length;
    while(carry!=0)
    {
        c.ans[j++]=carry%10;
        carry=carry/10;
    }
    c.length=j;
    return c;
}
bigInt operator-(bigInt a,bigInt b)
{
    bigInt c;
    int carry=0;
    int length_small=(a.length>b.length)?b.length:a.length;
    for(int i=0;i<length_small;i++)
    {
        if(a.ans[i]<(b.ans[i]+carry))
        {
            c.ans[i]=10+a.ans[i]-b.ans[i]-carry;
            carry=1;
        }
        else
        {
            c.ans[i]=a.ans[i]-b.ans[i]-carry;
            carry=0;
        }
    }
    if(a.length>b.length)
    {
        for(int i=b.length;i<a.length;i++)
        {
            if(a.ans[i]<carry)
            {
                c.ans[i]=10+a.ans[i]-carry;
                carry=1;
            }
            else
            {
                c.ans[i]=a.ans[i]-carry;
                carry=0;
            }
        }
    }
    else if(a.length<b.length)
    {
        for(int i=a.length;i<b.length;i++)
        {
            if(a.ans[i]<carry)
            {
                c.ans[i]=10+b.ans[i]-carry;
                carry=1;
            }
            else
            {
                c.ans[i]=b.ans[i]-carry;
                carry=0;
            }
        }
    }
    for(int i=max(a.length,b.length);i>=0;i--)
    {
        if(c.ans[i]!=0)
        {
            c.length=i+1;
            break;
        }
    }
    return c;
}

bigInt operator+(bigInt a,bigInt b)
{
    bigInt c;
    int carry=0;
    int length_small=(a.length>b.length)?b.length:a.length;
    for(int i=0;i<length_small;i++)
    {
        int tp=a.ans[i]+b.ans[i]+carry;
        c.ans[i]=tp%10;
        carry=tp/10;
    }
    if(a.length>b.length)
    {
        for(int i=b.length;i<a.length;i++)
        {
            int tp=a.ans[i]+carry;
            c.ans[i]=tp%10;
            carry=tp/10;
        }
        if(carry==1)
        {
            c.ans[a.length]=carry;
            c.length=a.length+1;
        }
        else
        {
            c.length=a.length;
        }
    }
    else if(a.length<b.length)
    {
        for(int i=a.length;i<b.length;i++)
        {
            int tp=b.ans[i]+carry;
            c.ans[i]=tp%10;
            carry=tp/10;
        }
        if(carry==1)
        {
            c.ans[b.length]=carry;
            c.length=b.length+1;
        }
        else
        {
            c.length=b.length;
        }
    }
    else
    {
        if(carry==1)
        {
            c.ans[a.length]=1;
            c.length=a.length+1;
        }
        else
        {
            c.length=a.length;
        }
    }
    return c;
}


int main()
{
    int a,b,c;
    int N;
    cin>>a>>b>>c>>N;
    bigInt *res=new bigInt[N+1];
    res[0]=1;
    res[1]=a+1;
    res[2]=b+a+a*a+1;
    for(int i=3;i<=N;i++)
    {
        res[i]=res[i-3]*c+(res[i-2]-res[i-3])*b+(res[i-1]-res[i-2])*a+res[i-1];
    }
    res[N].print();
    return 0;
}


你可能感兴趣的:(斐波那契,大数字)